Home > Back-end >  Is it legal to initialize a POD member of a base class before its constructor is called when it'
Is it legal to initialize a POD member of a base class before its constructor is called when it'

Time:11-27

In the following code:

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 ) ) {}
};

Derived::Derived changes a POD member variable Base::v before calling Base::Base. It's known that Base::Base isn't touching v at all. The goal is to have Base::v initialized to 42 after leaving Derived::Derived.

While this should technically work (Base::v already has space allocated for it in memory when Derived::Derived is called, and no code in Base::Base is ever touching it), the question is, is this legal? More specifically, does this at any point imply any undefined behavior, which compilers famously like to optimize-out?

Note that this question is purely for language lawyers. I'm not asking whether there are better ways of doing this (in most cases there obviously are), and I'm not trying to solve any specific problem other than trying to learn more about C from the point of view of the C standard.

CodePudding user response:

No, that is not valid:

class.cdtor/1

For an object with a non-trivial constructor, referring to any non-static member or base class of the object before the constructor begins execution results in undefined behavior.

Also see the example below the above paragraph:

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
  }
};
  • Related