-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Full name of submitter (unless configured in github; will be published with the issue): Matthew House
Reference (section label): [class.cdtor] paragraph 2
Link to reflector thread (if any):
Issue description:
According to [class.cdtor] paragraph 2,
During the construction of an object, if the value of the object or any of its subobjects is accessed through a glvalue that is not obtained, directly or indirectly, from the constructor's
this
pointer, the value of the object or subobject thus obtained is unspecified.
Consider the following example:
#include <iostream>
struct A {
A() : i(42) {}
int i;
};
struct B : virtual A {
B(int* p) { std::cout << *p << '\n'; }
};
struct C : virtual A, B {
C() : B(&i) {}
};
int main() { C c; }
Since the A
object is a (virtual) base class subobject of the B
object, and since i
is a member subobject of the A
object, i
is a subobject of the B
object. Therefore, the wording implies that accessing i
via *p
in B
's constructor yields an unspecified value, since p
was not obtained from the this
pointer of B
's constructor, but instead from the this
pointer of C
's constructor.
This is problematic for virtual bases that store pointers to their own subobjects. Consider the following example:
#include <iostream>
struct A {
A() : i(42), p(&i) {}
A(const A&) = delete;
A& operator=(const A&) = delete;
int i;
int* p;
};
struct B : virtual A {
B() { std::cout << *p << '\n'; }
};
struct C : virtual A, B {};
int main() { C c; }
Here, the value of p
was obtained from the this
pointer of A
's constructor, which was obtained directly from the this
pointer of C
's constructor. Therefore, accessing subobject i
via *p
in B
's constructor again yields an unspecified value.
I suggest loosening this restriction to allow base class constructors to receive subobject pointers from constructors of derived classes.
Suggested resolution:
Change [class.cdtor] paragraph 2 as follows:
During the construction of an object, if the value of the object or any of its subobjects is accessed through a glvalue that is not obtained, directly or indirectly, from the
constructor'sthis
pointer of the constructor invoked to initialize the most derived object, the value of the object or subobject thus obtained is unspecified.