You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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>structA {
A() : i(42) {}
int i;
};
structB : virtual A {
B(int* p) { std::cout << *p << '\n'; }
};
structC : virtual A, B {
C() : B(&i) {}
};
intmain() { 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>structA {
A() : i(42), p(&i) {}
A(const A&) = delete;
A& operator=(const A&) = delete;
int i;
int* p;
};
structB : virtual A {
B() { std::cout << *p << '\n'; }
};
structC : virtual A, B {};
intmain() { 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.
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.
The text was updated successfully, but these errors were encountered:
GCC devs have interpreted this paragraph to imply that no aliasing takes place between this and any constructor parameters, for which the wording isn't strong enough.
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,
Consider the following example:
Since the
A
object is a (virtual) base class subobject of theB
object, and sincei
is a member subobject of theA
object,i
is a subobject of theB
object. Therefore, the wording implies that accessingi
via*p
inB
's constructor yields an unspecified value, sincep
was not obtained from thethis
pointer ofB
's constructor, but instead from thethis
pointer ofC
's constructor.This is problematic for virtual bases that store pointers to their own subobjects. Consider the following example:
Here, the value of
p
was obtained from thethis
pointer ofA
's constructor, which was obtained directly from thethis
pointer ofC
's constructor. Therefore, accessing subobjecti
via*p
inB
'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:
The text was updated successfully, but these errors were encountered: