Date: Sat, 24 Dec 2022 10:55:47 -0500
According to 11.9.5 [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.
This wording implies that the following program outputs an unspecified
value:
#include <iostream>
struct A {
A() : i(0) {}
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, accessing i in B's constructor
yields an unspecified value, since it was not obtained from the this
pointer of B's constructor, but instead from the this pointer of C's
constructor.
With a strict reading of "obtained from", this wording also implies
that a self-referential pointer initialized in A's constructor yields
an unspecified value when accessed from B's constructor, since A's
constructor obtained its this pointer directly from C's constructor.
For instance, it implies that the following program also outputs an
unspecified value:
#include <iostream>
struct A {
A() : i(0), 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; }
Is this intended behavior, or a defect in the Standard?
> 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.
This wording implies that the following program outputs an unspecified
value:
#include <iostream>
struct A {
A() : i(0) {}
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, accessing i in B's constructor
yields an unspecified value, since it was not obtained from the this
pointer of B's constructor, but instead from the this pointer of C's
constructor.
With a strict reading of "obtained from", this wording also implies
that a self-referential pointer initialized in A's constructor yields
an unspecified value when accessed from B's constructor, since A's
constructor obtained its this pointer directly from C's constructor.
For instance, it implies that the following program also outputs an
unspecified value:
#include <iostream>
struct A {
A() : i(0), 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; }
Is this intended behavior, or a defect in the Standard?
Received on 2022-12-24 15:55:58