我能相信C编译器每次访问一个位字段时都是模2^n吗?
或者有没有编译器/优化,像下面这样的代码不会打印溢出?
struct {
uint8_t foo:2;
} G;
G.foo = 3;
G.foo++;
if(G.foo == 0) {
printf("Overflow\n");
}
提前谢谢你,弗洛里安
最佳答案
是的,您可以相信C编译器在这里做正确的事情,只要位字段是用unsigned类型声明的,这是用uint8_t
声明的。根据C99标准第6.2.6.1/3节:
存储在无符号位字段和无符号字符类型对象中的值应使用纯二进制表示法表示。40)
从6.7.2.1/9节:
位字段被解释为由指定位数组成的有符号或无符号整数类型。104)如果值0或1存储在类型_Bool
的非零宽度位字段中,则位字段的值应与存储的值相等。
以及第6.2.5/9条(重点矿井):
有符号整数类型的非负值范围是相应无符号整数类型的子范围,并且每种类型中相同值的表示形式都相同。31)涉及无符号操作数的计算永远不会溢出,因为不能由结果的无符号整数类型表示的结果是按比结果类型可以表示的最大值大一个的数字的模来减少的。
所以是的,您可以确保任何符合标准的编译器都会有G.foo
溢出到0,而不会有任何其他不必要的副作用。
关于c - 位字段溢出,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4908300/