C标准的第3.15.3节规定:
“如果在它们之间声明的所有成员也是非零长度位域,则在同一结构中同时更新两个非原子位域是不安全的,无论这些中间位域的大小是多少”。
考虑以下示例:
struct S {
unsigned a: 8;
unsigned b: 4;
unsigned c: 4;
unsigned d: 8;
};
Run Code Online (Sandbox Code Playgroud)
根据标准,这不是安全更新位字段a和d兼任。
为什么不?
位字段不能单独寻址,因此要设置位字段,编译器使机器代码可以:
有时,这是在一条指令中完成的,但随后处理器执行相同的工作。
无论哪种方式,如果另一个线程同时对同一字节中的其他位执行相同的操作,则这两个线程的操作可能会相互干扰。
另请注意:例如,您不能依赖于访问单位是字节,它可以是整数int或unsigned。