零初始化结构保证擦拭填充区域? [英] Is zero initialization of structures guaranteed to wipe padded areas?

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

问题描述

假设我有以下结构:

  typedef结构
{
    无符号field1的:1;
    无符号场2:1;
    无符号FIELD3:1;
} MYTYPE;

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

  MYTYPE testfields = {0};

  MYTYPE myfields = {1,1,1};

这样的,它是安全的执行以下 memcmp()在该位4..29将为零,因此不会影响到比较的假设:

 如果(memcmp(安培; myfields,&安培; testfields,sizeof的(myfields))== 0)
    的printf(字段有没有位设置\\ n);
其他
    的printf(字段有位设置\\ n);


解决方案

是,也不是。实际的标准,C11,规定:


  

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


  
  

      
  • ...


  •   
  • ,如果它是一个聚合,每件被初始化(递归的)
      根据这些规则,任何填充被初始化为零位;


  •   

因此​​,这仅适用于静态存储的目的,在第一图。但后来它说,除了:


  

如果有比有大括号括起来的列表少初始化
  是元件或聚集体的成员,或在更少的字符
  字符串用来初始化已知大小比有数组
  在数组中的元素,将总的剩余部分应
  初始化隐含一样具有静态存储对象
  持续时间。


因此​​,这意味着该子结构内填充未明确初始化为零位初始化

在summarry,在一个结构中的一些填充保证是零位初始化,一些则不是。我不认为这样的混乱是故意的,我将提交一份缺陷报告这一点。

旧版本没有,在所有。因此,与大多数现有的编译器,你不得不更加小心,因为他们没有实现C11,但。但是AFAIR,铛已经做代指。

另外要注意,这仅适用于初始化。填充不一定复制的分配。

Suppose I have the following structure:

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

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

or:

mytype myfields = {1, 1, 1};

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\n");
else
    printf("Fields have bits set\n");

解决方案

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

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;

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

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.

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.

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.

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

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