【问题标题】:Zero initialization of PODPOD的零初始化
【发布时间】:2012-12-23 09:17:43
【问题描述】:
struct Line
{
    Bounds          bounds_;
    Vector          origin_;
    uint32_t        begin_; 
    uint32_t        end_;   
    dist            ascent_;
    dist            descent_;
};

具体用法如下:

Line line = {};
while (!parser.done()) {
    line = Line(); // zero-initialize
    ...
}

BoundsVector 是非 POD 类,distint64_t 的 typedef。

但是,VC++11 的一个优化的 32 位版本似乎至少在 while 循环中留下了部分 line 未初始化。为什么?按照Do the parentheses after the type name make a difference with new?的说法,应该是零初始化了吧?

我将结构成员的值记录到文件中:

  • Line line = {};之后:非POD类型默认初始化,其他为0。
  • line = Line(); 之后:POD 类型仍默认初始化,其他包含随机值。

【问题讨论】:

  • 您对此有何看法?通过正常运行程序并在代码中进行测试,还是在调试器中查看?
  • @chris:是值初始化,我认为在这种情况下相当于零初始化。
  • @R.MartinhoFernandes:通过将值写入日志文件。在调试器下运行时,用于变量的内存位置恰好被清零,因此不可见。
  • @Nawaz,哦,我一定很困惑。出于某种原因,我认为Line() 会默认初始化它,而那些已初始化的将在分配给一个时初始化。

标签: c++ visual-c++ initialization compiler-bug


【解决方案1】:

您可能发现了一个编译器错误,尽管我似乎记得在 C++98 中初始化 POD 结构的要求并没有像描述的那样清楚。

根据 C++03,表达式Line() 必须产生一个值初始化 Line 对象,在这种情况下,这意味着所有成员都必须零初始化 em>(因为所有成员都是标量)。

请注意,成员之间的最终填充不必设置为任何确定的值,因此当您将 Line 对象视为内存块时,这可能会导致误报。

解决方法是为Line 提供一个默认构造函数,显式初始化所有成员。

【讨论】:

  • 是的,它看起来确实像一个编译器错误。我会更新我的问题。
  • 我对代码进行了一些尝试,它看起来像是 32 位 VC11 编译器的优化器错误。它只是忘记对 POD 结构成员进行零初始化。编译无优化,或使用 64 位编译器生成正确的汇编代码。
猜你喜欢
  • 1970-01-01
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-29
  • 2018-07-26
  • 1970-01-01
相关资源
最近更新 更多