考虑以下代码:

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/

10-10 16:24