c++make-shared

Does std::make_shared value initialize class members whose default ctor does not initialize?


Does std::make_shared value initalize members when there is a default ctor that fails to initailize its members?

I stumbled upon this when using a class where the default ctor did not initialize members using RAII style gave a warning and wondered why no warning was issued when it was used before elsewhere. Elsewhere it was using std::make_shared and I was thinking why it had been working before and no warning was issued.

#include <iostream>
#include <memory>

class Foo
{
public:
    Foo() {} // should initalize mode but does not

    int mode;

    bool isZero() const
    {
        if (mode == 0) {
            return true;
        }
        return false;
    }
};

int main(int argc, const char* argv[])
{
    auto blaa = std::make_shared<Foo>();
    if (blaa->isZero()) { // No warning. Always zero initialized because using make_shared?
        std::cout << "blaa.mode is zero\n";
    }
    Foo foo;
    if (foo.isZero()) { // warning: 'foo' is used uninitialized in this function - as expected
        std::cout << "foo.mode is zero\n";
    }
    return 0;
}

Solution

  • No, make_shared does not do anything different, with respect to constructing an object, than otherwise happens when an object gets constructed in any other way. All objects follow the same rules when they get constructed in C++.

    Your constructor fails to initialize mode. Just because it happens to be zero, when it's constructed in dynamic scope, with your compiler, and your operating system: that doesn't mean anything, and this does not give you any guarantees as to what happens when the object gets constructed in automatic scope (or vice versa).

    This is undefined behavior. As far as compiler warnings go: the compiler is not obligated to issue a warning message for undefined behavior. Any such warning message should simply be considered to be an unexpected bonus and a surprise. Your compiler does not detect undefined behavior in one of your two test cases, and that's simply how it is.