在C ++中是否将额外字节初始化为0?

时间:2018-05-07 20:03:24

标签: c++ memory initialization

假设我有一个包含int和char的结构:

struct thing_t {
    int value = 0;
    char other_value = 0;
};

由于事物在内存中的对齐方式,sizeof(thing_t)应为8,因为最大成员的大小为4个字节。如果我创建一个默认初始化的thing_t实例,那么额外的3个字节是否会被初始化为0?

我认识到这通常不会出现,但我正在编写一个哈希函数,哈希函数的默认行为是将泛型类型哈希,就像它是一个字节数组一样。如果额外的字节偶尔没有初始化为0,我意识到我的方法可能会导致问题。

3 个答案:

答案 0 :(得分:3)

我无法在C ++ 11标准中找到任何关于默认初始化对象时填充会发生什么的内容。

然而,标准是关于填充零初始化时的标准。

来自8.5 Initializers/5

  

5.2 - 如果T是一个(可能是cv限定的)非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的,并且填充初始化为零位;

     

5.3 -   如果T是(可能是cv限定的)联合类型,则对象的第一个非静态命名数据成员被零初始化并且填充被初始化为零位;

我建议使用零初始化而不是默认初始化来强制填充位初始化为零。这将导致哈希函数的可预测值。

答案 1 :(得分:3)

  

如果我创建了thing_t的默认初始化实例,那么额外的3个字节是否会初始化为0?

他们可能会也可能不会。没有要求将它们归零。

不幸的是,您无法对对象进行值初始化以使其初始化为零,这会使填充位为零,因为默认成员初始化器会阻止它被简单地构造。

[dcl.init]/8

  

对T类型的对象进行值初始化意味着:

     

[...]

     
      
  • 如果T是没有用户提供或删除的默认构造函数的(可能是cv限定的)类类型,则对象将进行零初始化并检查默认初始化的语义约束,如果T具有一个非平凡的默认构造函数,该对象是默认初始化的;
  •   

[class.ctor]/6

  

如果默认构造函数不是用户提供的,并且如果:

,则默认构造函数是微不足道的      

[...]

     
      
  • 其类的非静态数据成员没有默认成员初始值设定项(12.2)
  •   

答案 2 :(得分:0)

实际演讲:(考虑其他答案)

你应该删除" = 0"从你的struct初始化,否则你不能做值或零初始化(因为你隐式定义了一个默认的构造函数)。

struct thing_t {
    int value;
    char other_value;
};

然后你可以进行零初始化:

thing_t thing = {};

编辑:哦!解决你的问题...不,它们不是,除非它们是静态全局变量,但你可以使用值/零初始化来实现它。