1. What are the specific problems that are being avoided with the restrictions imposed by this clause `12.7p3` (see the first part of paragraph below)?
2. In the example shown in `12.7p3` (see below) why `X(this)` is considered defined? Is it because `X` is not in the path `E C D B A` ?
struct A { };
struct B : virtual A { };
struct C : B { };
struct D : virtual A { D(A*); };
struct X { X(A*); };
struct E : C, D, X {
E() : D(this), // undefined: upcast from E* to A*
// might use path E* - D* - A*
// but D is not constructed
// D((C*)this), // defined:
// E* - C* defined because E() has started
// and C* - A* defined because
// C fully constructed
X(this) { // defined: upon construction of X,
// C/B/D/A sublattice is fully constructed
}
};
3. Please find below the start of paragraph `12.7p3`:
To explicitly or implicitly convert a pointer (a glvalue) referring to
an object of class X to a pointer (reference) to a direct or indirect
base class B of X, the construction of X and the construction of all
of its direct or indirect bases that directly or indirectly derive
from B shall have started and the destruction of these classes shall
not have completed, otherwise the conversion results in undefined
behavior.
Is it correct to say that the set of all direct and indirect bases of `X`, mentioned above don't include `B`, and because of this the code below is well defined, notwithstanding the fact that `Base` is a direct base of `Derived` and has yet not started?
struct Base{ Base(Base*); };
struct Derived : Base {
Derived() : Base(this) {};
};
Yes.
complete E object.
pretty complicated).
You don't have ANY of those problems.