假设您有一个指向大于 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/