位字段如何与C中的位填充相互作用 [英] How do bit fields interplay with bits padding in C

查看:118
本文介绍了位字段如何与C中的位填充相互作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have two questions concerning bit fields when there are padding bits.

说我有一个结构定义为

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

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

Struct T only has two bits actually used.

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

Question 1: are these two bits always the least significant bits of the underlying unsigned int? Or it is platform dependent?

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

Question 2: Are those unused 30 bits always initialized to 0? What does the C standard say about it?

推荐答案

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

Question 1: are these two bits always the least significant bits of the underlying unsigned int? Or it is platform dependent?

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

No, it is both system and compiler dependent. You can never assume or know that they are MSB or LSB.

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

Question 2: Are those unused 30 bits always initialized to 0? What do the C and C++ standards say about it?

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

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 };.

来源

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

The language-lawyer details of why the above works are somewhat complex.

C17 6.7.9/9(重点是我)说:

C17 6.7.9/9 (emphasis mine) says this:

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

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.

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

This means that we cannot trust padding bits/bytes at all. But then there's this exception to the above rule (§20 emphasis mine):

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

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(强调我的意思):

C17 6.7.9/10 (emphasis mine):

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

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;

这篇关于位字段如何与C中的位填充相互作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆