在C中,位字段如何与位填充相互作用
当有填充位时,我有两个关于位字段的问题 假设我有一个定义为在C中,位字段如何与位填充相互作用,c,struct,bit-manipulation,language-lawyer,C,Struct,Bit Manipulation,Language Lawyer,当有填充位时,我有两个关于位字段的问题 假设我有一个定义为 struct T { unsigned int x: 1; unsigned int y: 1; }; 结构T只有两个实际使用的位 问题1:这两位是否始终是基础无符号整数的最低有效位?还是依赖于平台 问题2:这些未使用的30位是否总是初始化为0?C标准是怎么说的 问题1:这两位是否始终是基础无符号整数的最低有效位?还是依赖于平台 不,它依赖于系统和编译器。您永远不能假设或知道它们是MSB或LSB 问题2:这些未使用
struct T {
unsigned int x: 1;
unsigned int y: 1;
};
结构T只有两个实际使用的位
问题1:这两位是否始终是基础无符号整数的最低有效位?还是依赖于平台
问题2:这些未使用的30位是否总是初始化为0?C标准是怎么说的
问题1:这两位是否始终是基础无符号整数的最低有效位?还是依赖于平台
不,它依赖于系统和编译器。您永远不能假设或知道它们是MSB或LSB
问题2:这些未使用的30位是否总是初始化为0?C和C++标准对此有何评论?p>
取决于如何初始化结构。未初始化的本地作用域结构可能包含填充位/字节中的垃圾值。使用至少一个初始值设定项集初始化的结构,即使在填充字节中也保证包含零:my_struct={something}代码>
来源
语言律师详细说明了为什么上述工作有些复杂
C17 6.7.9/9(强调矿山)规定:
除另有明确规定外,为本款之目的,未命名
结构和联合类型的对象的成员不参与初始化。
结构对象的未命名成员即使在初始化后也具有不确定的值。
这意味着我们根本不能信任填充位/字节。
但上述规则还有一个例外(§20):
如果大括号内的列表中的初始值设定项少于元素或成员
用于初始化已知数组的字符串文字中的聚合字符数或更少字符数
尺寸大于阵列中的元素,骨料的剩余部分应
与具有静态存储持续时间的对象隐式初始化相同。
这意味着,如果至少有一个初始值设定项,则以下静态存储初始化规则适用:
C17 6.7.9/10(重点矿山):
如果具有静态或线程存储持续时间的对象未初始化
明确地说,那么:/--/
- 如果它是一个聚合,则根据这些规则(递归地)初始化每个成员,任何填充都初始化为零位李>
请只问一个问题,虽然C和C++标准可能会说类似的事情,但仍然存在差异,使得语义非常不同。(.未使用的位是不可访问的,并且不能保证初始化为任何特定值。如果这对您很重要,请不要使用位字段。位字段几乎没有任何可移植性,除了它们存在并在给定平台上工作(但它们存在并在其他平台上工作不同).作为记录,这些都不是律师的问题。当你必须在嵌入式平台上操作寄存器位时,这有点重要。