位字段如何与C

时间:2019-05-20 07:36:02

标签: c struct bit-manipulation language-lawyer

当存在填充位时,我有两个关于位字段的问题。

说我有一个结构定义为

struct T { 
    unsigned int x: 1; 
    unsigned int y: 1;
};

结构T仅具有实际使用的两位。

问题1:这两位始终是基础无符号int的最低有效位吗?还是取决于平台?

问题2:那些未使用的30位是否总是初始化为0? C标准怎么说?

1 个答案:

答案 0 :(得分:5)

  

问题1:这两位始终是基础无符号int的最低有效位吗?还是取决于平台?

否,它既取决于系统,也取决于编译器。您永远无法假设或知道它们是MSB或LSB。

  

问题2:那些未使用的30位是否总是初始化为0? C和C ++标准对此有何评论?

取决于如何初始化结构。在本地范围内未初始化的结构可能包含填充位/字节中的垃圾值。使用至少一个初始化程序集进行初始化的结构,即使在填充字节my_struct = { something };中也保证包含零。


来源

上述原因为何的语言律师细节有些复杂。

C17 6.7.9 / 9(强调我的意思)说:

  

除非另有明确说明,否则就本款而言,未命名   结构和并集类型的对象的成员不参与初始化。   结构对象的未命名成员即使在初始化后也具有不确定的值。

这意味着我们完全不能相信填充位/字节。 但是上面的规则(§20强调我的规则)有一个例外:

  

如果括号括起来的列表中的初始化程序少于元素或成员   的总和,或者用于初始化已知数组的字符串文字中的字符较少   大于数组中元素的大小,余数应为   初始化与具有静态存储持续时间的对象相同。

意思是,如果至少有一个初始化程序,则适用以下静态存储初始化规则:

C17 6.7.9 / 10(重点是我):

  

如果具有静态或线程存储持续时间的对象未初始化   明确地,然后:/-/

     
      
  • 如果是聚合,则根据这些规则初始化(递归)每个成员,并且任何填充都初始化为零位;
  •