Inspired by my (currently deleted) answer to this question (but there's a summary in my comment thereto), I was wondering whether the constructor for the Derived
class in the code below exhibits undefined behaviour.
#include <iostream>
class Base {
public:
Base(int test) {
std::cout << "Base constructor, test: " << test << std::endl;
}
};
class Derived : public Base {
private:
int variable;
public: Derived() : Base(variable = 50) { // Is this undefined behaviour?
}
};
int main()
{
Derived derived;
return 0;
}
I know that, when the base c'tor is called, the derived object has not yet (formally) been constructed, so the lifetime of the variable
member has not yet started. However, this excerpt from the C++ Standard (thanks to NathanOliver for the reference) suggests (maybe) that the object may be used "in limited ways" (bolding mine):
7 Similarly, before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any glvalue that refers to the original object may be used but only in limited ways. For an object under construction or destruction, see [class.cdtor]. Otherwise, such a glvalue refers to allocated storage ([basic.stc.dynamic.allocation]), and using the properties of the glvalue that do not depend on its value is well-defined. …
Clearly, if variable
were a object which itself had a non-trivial constructor, there would (almost certainly) be undefined behaviour here. However, for a primitive (or POD) type like an int
, can we assume that the storage for it has been allocated? And, if so, does the last phrase of the above quote hold, or is this still UB?
As an aside, neither clang-cl nor MSVC, even with full warnings enabled, give any diagnostic for the code shown, and it runs as expected. However, I appreciate that neither of those tools qualify as a formal interpretation/enforcement of the C++ Standard.