C语言中位字段的并发更新
C标准第3.15.3节规定: “同时更新中的两个非原子位字段是不安全的 如果在它们之间声明的所有成员也是 非零长度的位字段,无论其大小如何 中间的位字段正好是。” 考虑以下示例:C语言中位字段的并发更新,c,C,C标准第3.15.3节规定: “同时更新中的两个非原子位字段是不安全的 如果在它们之间声明的所有成员也是 非零长度的位字段,无论其大小如何 中间的位字段正好是。” 考虑以下示例: struct S { unsigned a: 8; unsigned b: 4; unsigned c: 4; unsigned d: 8; }; 根据该标准,同时更新位字段a和d是不安全的 为什么不呢?位字段不能单独寻址,因此要设置位字段,编译器会将机器代码设置为: 读取包含要设置的位的字节 在该字
struct S {
unsigned a: 8;
unsigned b: 4;
unsigned c: 4;
unsigned d: 8;
};
根据该标准,同时更新位字段a
和d
是不安全的
为什么不呢?位字段不能单独寻址,因此要设置位字段,编译器会将机器代码设置为:
另外请注意:访问单位不能依赖于字节,例如,它可以是一个完整的
int
或无符号的。我知道位字段不能单独寻址。但我不明白为什么标准上说“无论大小”。如果上面的位字段b和c的大小是,比如说64和64(在这里组成),标准说同时更新a和d(它们之间的间隔超过16字节)是不安全的。所以,它并没有明确回答这个问题。好吧,处理器使用128位以上的字的时候可能会有,也可能会有。仅仅因为我们的普通CPU有64位宽度,而且大多数人认为这已经足够了,所以这不需要刻在石头上。我认为标准不想设置限制。@user3124390它说“无论大小”,因为另一种选择是提供与特定大小图案分离的保证。这将是复杂的,并且将意味着标准不希望做出的实现选择。相反,它们为您提供了明确的机制来分隔它们——0大小的位字段。这很有意义。