未初始化的局部变量,默认为c ++ 11

时间:2014-08-26 08:45:56

标签: c++ c++11 undefined-behavior default-constructor

为什么打印b.k时打印a.k会发出警告?我使用VS2013

//warning C4700: uninitialized local variable 'b' used
#include<iostream> 

using namespace std;

struct A {
  A() {};
  int k;
};
struct B {
  B() = default;
  int k;
};

int main() {
  A a;
  cout << a.k << endl;
  B b;
  cout << b.k << endl; // this gives a warning, uninitialized local variable

  return 0;
}

2 个答案:

答案 0 :(得分:8)

访问未初始化的变量是未定义的行为,不需要诊断。这意味着您可以获得b.k(MSVC ++),a.k(g ++)或两者(Clang)的警告。

标准报价:

12.6.2初始化基础和成员[class.base.init]

  

8在非委托构造函数中,如果是给定的非静态数据成员   或者基类不是由mem-initializer-id指定的(包括   因为构造函数没有mem-initializer-list的情况   没有ctor-initializer)并且实体不是虚拟基类   抽象类(10.4),然后

     

[一堆不适用的条款]

     

- 否则,实体默认初始化(8.5)。

8.5初始值设定项[dcl.init]

  

7默认初始化T类型的对象意味着:

     

[一堆不适用的条款]

     

- 否则,不会执行初始化。

12.6.2 / 8引用有这个例子:

struct C {
    C() { }    // initializes members as follows:
    A a;         // OK: calls A::A()
    const B b;   // error: B has no default constructor
    int i;       // OK: i has indeterminate value // <---------- your code
    int j = 5;   // OK: j has the value 5
};

答案 1 :(得分:2)

根据§8.5初始化程序

if T has a non-trivial default constructor, the object is default-initialized;

这意味着两个a.k and b.k都未进行值初始化,访问它们为UB

要初始化A::k,您可以将其放入成员初始化列表

A():k(42) {};

对于B::K,您可以使用以下方式调用它:

B b = {}; // value initialize  members, k initialized to 0