gpt4 book ai didi

c - 位域和序列点

转载 作者:太空狗 更新时间:2023-10-29 16:31:19 24 4
gpt4 key购买 nike

对于将f0f1打包成同一个字节的实现,是否定义了下面的程序?

struct S0 {
unsigned f0:4;
signed f1:4;
} l_62;

int main (void) {
(l_62.f0 = 0) + (l_62.f1 = 0);
return 0;
}

如果有理由认为那里有所不同,我对 C99 和 C11 的答案很感兴趣。

在 C99 中,我只找到了 6.5:2:

Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. [...]

我不清楚这一段对上面的程序有什么影响。

基于大量随机测试,大多数编译器似乎会生成两个赋值不干扰的代码。

最佳答案

C11 将相邻的已命名 位字段视为同一内存位置的一部分。此类位字段不能保证以原子方式更新,换句话说,如果一个更新未明确排序在另一个更新之前,则行为未定义。 3.14 memory location 然后还详细解释了何时可以认为两个字段位于不同的内存位置,因此可以独立考虑对它们的更新。

如果你想修改你的结构

struct S0 {
unsigned f0:4;
int :0;
signed f1:4;
} l_62;

这样两个位域之间就有这个奇怪的“内存位置分隔符”,你的代码就可以保证没问题了。

C99 的情况似乎比较复杂,没有这么详细的内存位置概念。在最近关于 linux 内核邮件列表的讨论中,有人声称通常对于所有位字段对,在更新其中任何一个时都会保证原子性。该讨论的出发点是 gcc 以一种意想不到的方式污染了与位域相邻的非位域,从而导致虚假崩溃。

关于c - 位域和序列点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9151608/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com