当基类的 POD 成员不打算由它初始化时,在调用其构造函数之前初始化它是否合法?

dra*_*oot 2 c++ inheritance undefined-behavior language-lawyer

在下面的代码中:

class Base
{
protected:
  int v;

  Base( void * ) { /* doesn't touch v at any point */ }
};

class Derived: public Base
{
public:
  // Changes Base::v before calling Base::Base
  Derived(): Base( ( (void )( v = 42 ), nullptr ) ) {}
};
Run Code Online (Sandbox Code Playgroud)

Derived::DerivedBase::v在调用之前更改 POD 成员变量Base::Base。众所周知,这根本Base::Base没有触动。v目标是在离开后Base::v初始化为。42Derived::Derived

虽然这在技术上应该可行(调用Base::v时已经在内存中为其分配了空间Derived::Derived,并且没有代码Base::Base接触过它),但问题是,这合法吗?更具体地说,这是否在任何时候都意味着任何未定义的行为,而众所周知,编译器喜欢优化这些行为?

请注意,这个问题纯粹是针对语言律师的。我并不是在问是否有更好的方法来做到这一点(在大多数情况下显然有),并且除了尝试从 C++ 标准的角度了解更多关于 C++ 之外,我也没有试图解决任何特定问题。

Ted*_*gmo 5

不,这是无效的:

类.cdtor/1

对于具有非平凡构造函数的对象,在构造函数开始执行之前引用该对象的任何非静态成员或基类会导致未定义的行为。

另请参阅上面段落下面的示例:

struct W { int j; };
struct X : public virtual W { };
struct Y {
  int* p;
  X x;
  Y() : p(&x.j) {   // undefined, x is not yet constructed
  }
};
Run Code Online (Sandbox Code Playgroud)