提问人:Sparky McAnderson 提问时间:11/9/2023 最后编辑:Peter CordesSparky McAnderson 更新时间:11/9/2023 访问量:82
大于本机尺寸类型的商店订购 - C 规范
Store ordering for larger-than-native-size type - C spec
问:
假设你有一个指向大于本机类型整数的指针,最近的 C 规范对商店订购有什么看法?例如:
volatile uint64_t *test = (volatile uint64_t *)(addr);
*test = 0;
在 32 位架构上,这将编译为两个存储,C 规范是否说明哪个存储将是第一个(addr 或 addr+4)?还是定义了实现?
答:
最近的 C 规范对商店订购有何看法?
字节序是实现定义的。
C 规范是否说明了哪个商店将首先出现(addr 或 addr+4)?
它是实现定义的。它可能是同时进行的。它甚至不需要保持一致。
评论
volatile uint64_t *test = (volatile uint64_t *)(addr);
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 标准一直被打破,说的是对象而不是左值访问。在这里的代码中,指向的数据不一定是对象,也许只有指针才是。因为编译器可能不知道您从中转换指针的地址上存储了什么,或者该对象获得了什么“有效类型”和限定符。这个语言“错误”将在即将到来的 C23 标准中得到修复,该标准定义并使用术语易失性访问。volatile
volatile
volatile
评论
sig_atomic_t
volatile uint32_t
volatile sig_atomic_t
sig_atomic_t
int
volatile
volatile
addr
addr + 1
addr + 5