位域溢出 [英] Overflow in bit fields
问题描述
我可以相信每次访问位域时 C 编译器都会对 2^n 取模吗?或者是否有任何编译器/优化,其中像下面这样的代码不会打印出溢出?
can I trust that the C compiler does modulo 2^n each time I access a bit field? Or is there any compiler/optimisation where a code like the one below would not print out Overflow?
struct {
uint8_t foo:2;
} G;
G.foo = 3;
G.foo++;
if(G.foo == 0) {
printf("Overflow\n");
}
提前致谢,弗洛里安
推荐答案
是的,您可以信任 C 编译器在这里做正确的事情,只要位域是用无符号类型声明的,而您拥有 <代码>uint8_t.来自 C99 标准 §6.2.6.1/3:
Yes, you can trust the C compiler to do the right thing here, as long as the bit field is declared with an unsigned type, which you have with uint8_t
. From the C99 standard §6.2.6.1/3:
存储在无符号位域中的值和 unsigned char 类型的对象应使用纯二进制符号表示.40)
Values stored in unsigned bit-fields and objects of type unsigned char shall be represented using a pure binary notation.40)
来自 §6.7.2.1/9:
From §6.7.2.1/9:
位域被解释为由指定位数组成的有符号或无符号整数类型.104)如果值 0 或 1 存储到非零宽度位域键入 _Bool
,位域的值应与存储的值相等.
A bit-field is interpreted as a signed or unsigned integer type consisting of the specified number of bits.104) If the value 0 or 1 is stored into a nonzero-width bit-field of type
_Bool
, the value of the bit-field shall compare equal to the value stored.
来自 §6.2.5/9(强调我的):
And from §6.2.5/9 (emphasis mine):
有符号整数类型的非负值范围是对应的无符号整数类型的一个子范围,每个类型中相同值的表示是相同的.31) A涉及无符号操作数的计算永远不会溢出,因为无法由结果无符号整数类型表示的结果会以比结果类型可以表示的最大值大 1 的数为模减少.
The range of nonnegative values of a signed integer type is a subrange of the corresponding unsigned integer type, and the representation of the same value in each type is the same.31) A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.
所以是的,您可以确定任何符合标准的编译器都会将 G.foo
溢出到 0,而不会产生任何其他不需要的副作用.
So yes, you can be sure that any standards-conforming compiler will have G.foo
overflow to 0 without any other unwanted side effects.
这篇关于位域溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!