本文介绍了结构的零初始化是否保证擦除填充区域?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下结构:

typedef struct
{
    unsigned field1 :1;
    unsigned field2 :1;
    unsigned field3 :1;
} mytype;

前 3 位可用,但 sizeof(mytype) 将返回 4,这意味着 29 位填充.我的问题是,标准是否保证这些填充位由语句初始化为零:

The first 3 bits will be usable but sizeof(mytype) will return 4 which means 29 bits of padding.My question is, are these padding bits guaranteed by the standard to be zero initialized by the statement:

mytype testfields = {0};

或:

mytype myfields = {1, 1, 1};

假设第 4..29 位为零,因此不会影响比较,因此可以安全地执行以下 memcmp():

Such that it's safe to perform the following memcmp() on the assumption that bits 4..29 will be zero and therefore won't affect the comparison:

if ( memcmp(&myfields, &testfields, sizeof(myfields)) == 0 )
    printf("Fields have no bits set
");
else
    printf("Fields have bits set
");

推荐答案

是和不是.实际标准 C11 规定:

Yes and no. The actual standard, C11, specifies:

如果具有静态或线程存储持续时间的对象不是显式初始化,然后:

  • ....

  • ....

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

if it is an aggregate, every member is initialized (recursively)according to these rules, and any padding is initialized to zero bits;

所以这仅适用于静态存储的对象,乍一看.但后来它又说:

So this only holds for objects of static storage, at a first view. But then later it says in addition:

如果大括号括起来的列表中的初始值设定项比那里少是聚合的元素或成员,或用于初始化已知大小的数组的字符串文字是数组中的元素,聚合的其余部分应为隐式初始化与具有静态存储的对象相同持续时间.

所以这意味着未显式初始化的子结构内的填充是零位初始化的.

So this means that padding inside sub-structures that are not initialized explicitly is zero-bit initialized.

总之,结构中的一些填充保证是零位初始化的,有些则不是.我不认为这种混淆是故意的,我会为此提交一份缺陷报告.

In summarry, some padding in a structure is guaranteed to be zero-bit initialized, some isn't. I don't think that such a confusion is intentional, I will file a defect report for this.

旧版本根本没有.因此,对于大多数现有的编译器,您必须更加小心,因为它们还没有实现 C11.但是 AFAIR,clang 已经代表了这一点.

Older versions didn't have that at all. So with most existing compilers you'd have to be even more careful, since they don't implement C11, yet. But AFAIR, clang already does on that behalf.

还要注意,这仅适用于初始化.分配时不一定要复制填充.

Also be aware that this only holds for initialization. Padding isn't necessarily copied on assignment.

这篇关于结构的零初始化是否保证擦除填充区域?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 21:29