c - 商店订购大于原始尺寸的类型 - C 规范

标签 c assembly embedded volatile

假设您有一个指向大于 native 类型整数的指针,最近的 C 规范对存储排序有何规定?例如:

volatile uint64_t *test = (volatile uint64_t *)(addr);
*test = 0;

在 32 位架构上,这将编译为两个存储,C 规范是否说明了哪个存储将是第一个(addr 或 addr+4)?或者它是实现定义的?

最佳答案

C 标准没有提及商店订单。它可能按照寻址顺序发生,这意味着最低地址的数据可能首先被复制(大端上的MS字节,小端上的LS字节)。有可能(但不能保证),因为按照地址顺序进行复制对于大多数 ISA 来说是最有意义的,尤其是那些具有数据缓存的 ISA。


有些相关:

C 标准 (5.1.2.3) 所保证的是整个 64 位将被复制到此处的两个序列点之间:

... ;      // the semi colon is a sequence point
*test = 0; // the semi colon is a sequence point

由于未使用 _Atomic 限定符,因此无法保证原子性。因此,访问可能会因上下文切换到另一个线程或进程而中途中断 - 不保证访问是线程安全的。

5.1.2.3 不是该标准的最佳部分,但如果您逐字阅读它,那么它还表示指令重新排序不能在 volatile 对象上发生,本质上使其充当内存屏障。

然而,另一个“语言律师”方面是,自 C90 以来,C 标准一直被破坏,涉及 volatile 对象而不是 volatile 左值访问。在您的代码中,所指向的数据不一定是 volatile 对象,也许只是指针。由于编译器可能不知道您从中转换指针的地址存储了什么,或者该对象获得了什么“有效类型”和限定符。此语言“错误”将在即将发布的 C23 标准中得到修复,该标准定义并使用术语 volatile 访问

关于c - 商店订购大于原始尺寸的类型 - C 规范,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77448478/

相关文章:

rust - 如何在 ARM 嵌入式 Rust 中使用更少的内存进行取模

c++ - 字符串文字数组中字符串文字的编译时间大小

c - 当 C 中的静态分配没有足够的内存时会发生什么?

xcode - 如何在 Mac 框架中调用 cpuid 指令?

assembly - 如何只设置ARM汇编的溢出标志?

c++ - 是否有任何理由使用 C 而不是 C++ 进行嵌入式开发?

c - 在 GCC 中获取指针编译时间的低 16 位

java - 我可以在同一版本的 Eclipse 中创建 C++ 和 Java 项目吗?

更改使用 malloc 创建的指针的地址

assembly - 在 MIPS 中获取 32 位整数的 MSB,并将其合并到另一个值的 LSB