在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++标准可能会说类似的事情,但仍然存在差异,使得语义非常不同。(.未使用的位是不可访问的,并且不能保证初始化为任何特定值。如果这对您很重要,请不要使用位字段。位字段几乎没有任何可移植性,除了它们存在并在给定平台上工作(但它们存在并在其他平台上工作不同).作为记录,这些都不是律师的问题。当你必须在嵌入式平台上操作寄存器位时,这有点重要。