Search code examples
c++compilationinitialization

Are class members with a member initializer initialized again in the constructor if they are in the initializer list?


I have this class:

class A 
{
    bool isSomthing{true};
    A() : isSomthing{isSomthingFunc()}{};
    bool isSomthingFunc() {return isSomthing && isSomthingFuncExt()};
};

Can someone please explain what is going to be the value of isSomething if isSomthingFuncExt() returns false (what is going to happen in case isSomthingFuncExt() return val is constexpr and what if not)?


Solution

  • Your code invokes undefined behavior.

    The example seems to be made up to illustrate some wrong and very round about understanding of how initializers are used. However, it is actually rather simple: The default initializer is only used when there is no initializer in the member initializer list. Hence, in your example the default initializer is not used in the constructor.

    The constructor

    A() : isSomthing{isSomthingFunc()}{};
    

    uses isSomethingFunc() to initizliaze the member. It does NOT use the in-class default true initializer.

    You could write for the same effect:

    class A 
    {
        bool isSomthing;  // no default initializer !!
        A() : isSomthing{isSomthingFunc()}{};
        bool isSomthingFunc() {
            return isSomthing &&          // UB: reading before initialization
                   isSomthingFuncExt()
        };
    };
    

    Calling isSomthingFunc invokes undefined behavior, because it reads from the member before it has been initialized.

    For details I refer you to: https://en.cppreference.com/w/cpp/language/constructor ("If a non-static data member has a default member initializer and also appears in a member initializer list, then the member initializer is used and the default member initializer is ignored:").