Joh*_* Li 2 c struct bit-manipulation language-lawyer
当存在填充位时,我有两个关于位字段的问题。
说我有一个结构定义为
struct T {
unsigned int x: 1;
unsigned int y: 1;
};
Run Code Online (Sandbox Code Playgroud)
结构T仅实际使用了两位。
问题1:这两位始终是基础无符号int的最低有效位吗?还是取决于平台?
问题2:那些未使用的30位是否总是初始化为0?C标准对此有何评论?
问题1:这两位始终是基础无符号int的最低有效位吗?还是取决于平台?
不,它与系统和编译器有关。您永远无法假设或知道它们是MSB或LSB。
问题2:那些未使用的30位是否总是初始化为0?C和C ++标准对此有何评论?
取决于您如何初始化结构。在本地范围内未初始化的结构可能包含填充位/字节中的垃圾值。使用至少一个初始化程序集进行初始化的结构,即使在填充字节中也保证包含零:my_struct = { something };。
资料来源
有关上述原因的语言律师细节有些复杂。
C17 6.7.9 / 9(强调我的)说:
除非另有明确说明,否则出于本条的目的,结构和联合类型的对象的未命名成员不参与初始化。 结构对象的未命名成员即使在初始化后也具有不确定的值。
这意味着我们完全不能相信填充位/字节。但是上面的规则(§20强调我的规则)有一个例外:
如果用大括号括起来的列表中的初始化程序少于聚合中的元素或成员,或者用于初始化已知大小的数组的字符串文字中的字符少于该数组中的元素,则聚合的其余部分应与具有静态存储持续时间的对象一样隐式初始化。
这意味着,如果至少有一个初始化程序,则适用以下静态存储初始化规则:
C17 6.7.9 / 10(重点是我的):
如果没有显式初始化具有静态或线程存储持续时间的对象,则:/-/
- 如果是集合,则根据这些规则初始化每个成员(递归),并将任何填充初始化为零位;