The following program compiles but crashes at runtime. === test.cpp === struct A {}; struct B : virtual public A { B(A*) {} }; struct C { C() : b(&b) {} B b; }; int main() { new C; } ========= Command line: g++ -Wall test.cpp
The problem is that the lifetime of b has not been started yet so you get a crash (optimizing will remove the crash only because of inlining) so the behavior is undefined. From the C++ standard, 2.8 [basic.life]: The liftime of an object of type T begins when: — storage with the proper alignment and size for type T is obtained and (this is true but) — if T is a class type with a non-trrivial constructor (12.1), the constructor has completed (this is not so the behavior is undefined and could cause a crash). From 12.1.5 (Constructors): A constuctor is trival if it is an implictly-declared default constructor (this is not true in this example) and if ....
Does the standard say I can't take the address of an object that has already been allocated but not yet constructed?
Yes 12.7.2 : To explicitly or implicitly convert a pointer (an lvalue) refering 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. In your example the construtor of b have not started yet.