C中位域的并发更新

use*_*390 4 c

C标准的第3.15.3节规定:

“如果在它们之间声明的所有成员也是非零长度位域,则在同一结构中同时更新两个非原子位域是不安全的,无论这些中间位域的大小是多少”。

考虑以下示例:

struct S {
  unsigned a: 8;
  unsigned b: 4;
  unsigned c: 4;
  unsigned d: 8;
};
Run Code Online (Sandbox Code Playgroud)

根据标准,这不是安全更新位字段ad兼任。

为什么不?

Mat*_*ans 6

位字段不能单独寻址,因此要设置位字段,编译器使机器代码可以:

  1. 读取包含要设置的位的字节
  2. 在该字节中设置所需的位
  3. 将整个字节写回。

有时,这是在一条指令中完成的,但随后处理器执行相同的工作。

无论哪种方式,如果另一个线程同时对同一字节中的其他位执行相同的操作,则这两个线程的操作可能会相互干扰。

另请注意:例如,您不能依赖于访问单位是字节,它可以是整数intunsigned