Kaiyakha
Kaiyakha

Reputation: 1913

Why does default constructor only work with class pointers?

I've been messing around with a default constructor example inspired by this answer. This one works fine:

class Foo {
public:
    int x;
    Foo() = default;
};

int main() {    
    for (int i = 0; i < 100; i++) {
        Foo* b = new Foo();
        std::cout << b->x << std::endl;
    }

But when I try this out with a class instance on the stack it does not! For example, if I instantiate the class like Foo b I get an error saying uninitialised local variable 'b' used.

However, when I change the constructor to Foo() {}, instantiation with Foo b works fine, and I see random garbage from b.x as expected.

Why doesn't a default constructor work when I instantiate a class on the stack?

I compiled the code with MVSC C++17: Screenshot

Upvotes: 3

Views: 199

Answers (1)

Ted Lyngmo
Ted Lyngmo

Reputation: 117298

It's because x is uninitialized. Reading uninitialized variables makes your program have undefined behavior which means it could stop "working" any day. It may also do something odd under the hood that you don't realize while you think everything is fine.

These all zero-initialize x:

Foo* b = new Foo();
Foo* b = new Foo{};
Foo b{};

while these don't:

Foo *b = new Foo;
Foo b;

MSVC may not catch and warn about all cases where you leave a variable uninitialized and read it later. It's not required to do so - which is why you may get the warning in one case but not the other.

Upvotes: 7

Related Questions