If I cast "this" in a base class constructor to a derived class type, there is no warning even with -Wall -Wextra. Such a cast is undefined behavior, and seems like it should be diagnosed at compile time. For example: struct Base { Base(); int num; }; struct Derived : Base { int calc() const { return 42; } }; Base::Base() // UB: Derived not yet constructed : num(static_cast<Derived*>(this)->calc()) { } int main() { Derived d; return d.num; } It compiles cleanly with "-Wall -Wextra -Werror" in GCC 8 and 10, with and without optimization. I think it should produce a diagnostic such as "invalid static_cast from type ‘Base*’ to type ‘Derived*’ before the latter is constructed". UBSan reports the undefined behavior if Base has a virtual method (e.g. if you add "virtual ~Base() = default;"), but not with the code as written, making it even more advantageous to diagnose at compile time. Live demo: https://godbolt.org/z/x3fa4Y
I agree a diagnostic makes sense.
Hmm, is the cast undefined, actually? I thought you were right, but now can't find any wording to that effect. I see [expr.static.cast] If the prvalue of type “pointer to cv1 B” points to a B that is actually a base class subobject of an object of type D, the resulting pointer points to the enclosing object of type D. Otherwise, the behavior is undefined. But this B is a base of a D. Then [class.cdtor] For an object with a non-trivial constructor, referring to any non-static member or base class of the object before the constructor begins execution results in undefined behavior. but D() has begun execution. Then [class.cdtor] 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. but 'this' in the Base ctor seems to count as obtained indirectly from 'this' in the Derived ctor. Then [class.cdtor] paragraph 4 talks about virtual functions, which this is not. What rule makes this undefined?