相关疑难解决方法(0)

C++ 标准是否保证非静态聚合对象的填充字节初始化为零?

C++ 是否支持允许我们将对象及其所有填充字段初始化为零的语言构造。我在 cppreference.com 中发现了一些关于零初始化的令人鼓舞的措辞,表明在某些情况下,填充字节也将被清零。

引用自 cppreference.com: 零初始化

零初始化在以下情况下进行:

  1. 作为非类类型和没有构造函数的值初始化类类型的成员的值初始化序列的一部分,包括未提供初始化程序的聚合元素的值初始化。

零初始化的效果是:

  • 如果 T 是标量类型,则对象的初始值是显式转换为 T 的整数常量零。
  • 如果 T 是非联合类类型,则所有基类和非静态数据成员都初始化为零,并且所有填充都初始化为零位。构造函数(如果有)将被忽略。
  • ...

人们会在value-initializationaggregate-initializationlist-initialization中找到对零初始化的引用。

我使用相当最新的 GCC 和 clang C++ 编译器进行了测试,它们的行为似乎有所不同。

坦率地说,我努力解析这些规则,特别是考虑到不同的编译器行为,我无法弄清楚如何正确解释这些规则。

请参阅此处的代码(至少需要 C++11)。结果如下:

给出: Foo

struct Foo
{
    char x;
    int y;
    char z;
};
Run Code Online (Sandbox Code Playgroud)
构造 克++ 铿锵++
富() x:[----][0x42][0x43][0x44],v: 0 x:[----][----][----][----],v: 0
y:[----][----][----][----],v: 0 y:[----][----][----][----],v: 0
z:[----][0x4A][0x4B][0x4C],v: 0 z:[----][----][----][----],v: 0
富{} x:[----][----][----][----],v: 0 x:[----][0x42][0x43][0x44],v: 0
y:[----][----][----][----],v: 0 y:[----][----][----][----],v: 0
z:[----][----][----][----],v: 0 z:[----][0x4A][0x4B][0x4C],v: 0

这里[----] …

c++ gcc initialization language-lawyer zero-initialization

21
推荐指数
1
解决办法
2030
查看次数

结构零初始化是否保证擦除填充区域?

假设我有以下结构:

typedef struct
{
    unsigned field1 :1;
    unsigned field2 :1;
    unsigned field3 :1;
} mytype;
Run Code Online (Sandbox Code Playgroud)

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

mytype testfields = {0};
Run Code Online (Sandbox Code Playgroud)

要么:

mytype myfields = {1, 1, 1};
Run Code Online (Sandbox Code Playgroud)

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

if ( memcmp(&myfields, &testfields, sizeof(myfields)) == 0 )
    printf("Fields have no bits set\n");
else
    printf("Fields have bits set\n");
Run Code Online (Sandbox Code Playgroud)

c struct initialization

11
推荐指数
2
解决办法
1240
查看次数

初始化时的C struct padding

我有一个结构,如

typedef struct
{
    int a;  // Let's say this ends up being 4 bytes
    int b;  // 4 bytes
    char text[10]; // 10 bytes
} blah_t;

static blah_t myvar;
Run Code Online (Sandbox Code Playgroud)
  1. 假设字段的大小之和为18个字节blah_t,但sizeof(blah_t)由于填充而为20 个字节。
  2. myvar是静态的,因此这将是零初始化。

题:

  1. 对于静态变量,填充字节19和20是否保证为0?如果不是,我将需要使memset(&myvar, 0, sizeof(blah_t))任何memcmp结构有效-即使是静态变量也是如此。
  2. calloc(1, sizeof(blah_t))呢 字节19和20是否保证为零?我相信情况就是如此。

c struct padding calloc

4
推荐指数
1
解决办法
1482
查看次数