简体   繁体   English

位字段如何与C中的位填充相互作用

[英]How do bit fields interplay with bits padding in C

I have two questions concerning bit fields when there are padding bits. 当存在填充位时,我有两个关于位字段的问题。

Say I have a struct defined as 说我有一个结构定义为

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

Struct T only has two bits actually used. 结构T仅实际使用了两位。

Question 1: are these two bits always the least significant bits of the underlying unsigned int? 问题1:这两位始终是基础无符号int的最低有效位吗? Or it is platform dependent? 还是取决于平台?

Question 2: Are those unused 30 bits always initialized to 0? 问题2:那些未使用的30位是否总是初始化为0? What does the C standard say about it? C标准对此有何评论?

Question 1: are these two bits always the least significant bits of the underlying unsigned int? 问题1:这两位始终是基础无符号int的最低有效位吗? Or it is platform dependent? 还是取决于平台?

No, it is both system and compiler dependent. 不,它与系统和编译器有关。 You can never assume or know that they are MSB or LSB. 您永远无法假设或知道它们是MSB或LSB。

Question 2: Are those unused 30 bits always initialized to 0? 问题2:那些未使用的30位是否总是初始化为0? What do the C and C++ standards say about it? C和C ++标准对此有何评论?

Depends on how you initialize the struct. 取决于您如何初始化结构。 A struct at local scope which isn't initialized may contain garbage values in padding bits/bytes. 在本地范围内未初始化的结构可能包含填充位/字节中的垃圾值。 A struct that is initialized with at least one initializer set, is guaranteed to contain zero even in padding bytes: my_struct = { something }; 使用至少一个初始化程序集进行初始化的结构,即使在填充字节中也保证包含零: my_struct = { something }; .


Sources 来源

The language-lawyer details of why the above works are somewhat complex. 有关上述原因的语言律师细节有些复杂。

C17 6.7.9/9 (emphasis mine) says this: C17 6.7.9 / 9(强调我的)说:

Except where explicitly stated otherwise, for the purposes of this subclause unnamed members of objects of structure and union type do not participate in initialization. 除非另有明确说明,否则出于本节的目的,结构和联合类型的对象的未命名成员不参与初始化。 Unnamed members of structure objects have indeterminate value even after initialization. 结构对象的未命名成员即使在初始化后也具有不确定的值。

This means that we cannot trust padding bits/bytes at all. 这意味着我们完全不能相信填充位/字节。 But then there's this exception to the above rule (§20 emphasis mine): 但是上面的规则(§20强调我的规则)有一个例外:

If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate , or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration. 如果用大括号括起来的列表中的初始化程序少于聚合中的元素或成员 ,或者用于初始化已知大小的数组的字符串文字中的字符少于该数组中的元素,则聚合的其余部分应与具有静态存储持续时间的对象一样隐式初始化。

Meaning that if there's at least one initializer, then the following rule of static storage initialization applies: 这意味着,如果至少有一个初始化程序,则适用以下静态存储初始化规则:

C17 6.7.9/10 (emphasis mine): C17 6.7.9 / 10(重点是我的):

If an object that has static or thread storage duration is not initialized explicitly, then: /--/ 如果没有显式初始化具有静态或线程存储持续时间 的对象 ,则:/-/

  • if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits ; 如果是聚合,则根据这些规则初始化(递归)每个成员,并将任何填充初始化为零位

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM