考虑以下代码:
class A {
private:
int a;
public:
A(int a) : a(a) { }
};
class B : public A {
private:
int b;
bool init() {
b = 0;
return true;
}
public:
// init() is a hack to initialize b before A()
// B() : b(0), A(b) {} yields -Wreorder
// B() : A((b = 0)) {} no warning (but this one doesn't work so well with non-pod (pointer) types)
B() : A(init() ? b : 0) {}
};
现在尝试用clang编译此代码...
$ clang++ test.cpp -fsyntax-only
test.cpp:19:20: warning: field 'b' is uninitialized when used here [-Wuninitialized]
B() : A(init() ? b : 0) {}
^
1 warning generated.
即使使用
-Wall -Wextra
和-pedantic
,GCC也不会打印任何警告。 最佳答案
这是未定义的行为。根据[class.base.init]:
初始化b
基类时,尚未初始化A
。出于相同的原因,分配b = 0
本身是未定义的行为-调用时b
尚未初始化。它的默认构造函数仍将在A
的构造函数之后调用。
如果要确保首先初始化b
,则典型的方法是base-from-member idiom:
struct B_member {
int b;
B_member() : b(0) { }
};
class B : public B_member, public A
{
public:
B() : A(b) // B_member gets initialized first, which initializes b
// then A gets initialized using 'b'. No UB here.
{ };
};
关于c++ - 这是未定义的行为还是误报?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30144345/