Can a primitive-type data member of a derived class be used as a parameter to its base constructor?

14

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.

Share
Improve this question
7
  • 1
    Isn't this specific case moot since the base ctor takes the parameter by value? You might need a reference or pointer parameter to make this meaningful. – Mooing Duck Apr 15 at 16:10
  • I think the lifetime of variable starts before the lifetime of the enclosing Derived object. – HolyBlackCat Apr 15 at 16:10
  • @MooingDuck But does the variable member keep the given value in a well-defined manner? – Adrian Mole Apr 15 at 16:11
  • 2
    @AdrianMole: If I knew the answer to that, I would have posted an answer :P – Mooing Duck Apr 15 at 16:12
  • 1
    @Jarod42 Here's a better demo. Only Clang rejects it, GCC & MSVC stay silent. – HolyBlackCat Apr 15 at 16:23

Comments

Popular posts from this blog

Meaning of `{}` for return expression

Get current scroll position of ScrollView in React Native

flutter websocket connection issue