默认初始化时是否给予POD特殊处理(c ++ 14)?

时间:2018-05-07 11:46:25

标签: c++ c++11 c++14

为什么以下代码产生0作为输出?在我的理解中,它是默认初始化(而不是值初始化),因此值应该是随机的。

#include <stdio.h>
#include<iostream>
#include<memory>

using namespace std;

struct A 
{

    int i;
    int j;
};


int main()
{
    A a;

    cout << " i is " << a.i << endl;

    return 0;
}

来自cppreference:

默认初始化的效果是:

如果T是非POD(直到C ++ 11)类类型,则考虑构造函数并对空参数列表进行重载解析。选择的构造函数(它是默认构造函数之一)被调用以提供新对象的初始值;

如果T是数组类型,则数组的每个元素都是默认初始化的;

否则,什么都不做:具有自动存储持续时间的对象(及其子对象)被初始化为不确定值。

2 个答案:

答案 0 :(得分:3)

未定义a.i的价值,您应该获得任何价值。

取决于系统,使用的std库,编译器,编译器标志,...内存的某些部分(例如堆栈)可能会用0初始化,但不能保证

对于gcc也是如此,在您的简单示例中,您可能始终获得0,但如果您关闭优化-O0并编译以下代码:

#include <iostream>

struct A 
{
  int i;
  int j;
};


int foo() {
  A a;
  const int b = a.i;
  a.i = 123;
  return b;
}

int main() {
  const int n1 = foo();
  const int n2 = foo();
  std::cout << n1 << " " << n2 << std::endl;
  return 0;
}

然后(取决于os,std库,cpu ...),您将得到以下输出:

0 123

在这两种情况下,a.i未初始化,对于第一次通话,a.i会保留一些&#34;随机&#34; 号码,对于第二次通话,{{可能会在同一位置创建1}},因此内存的这一部分可能仍然保留a。原因是在堆栈上创建了123,随后对off A的调用很可能会导致foo位于堆栈上的相同内存地址上。 / p>

答案 1 :(得分:0)

基于讨论,实验。这是未定义的行为。 POD在默认初始化中没有特殊处理。

clang,MSVC总是给出随机值,但gcc总是给出0. Afterall,undefined是未定义的。