为什么打印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;
}
答案 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