1

Using Microsoft Visual Studio Ultimate 2013 update 4 and the following code:

#include <iostream>

auto main() -> int {
    struct Base { int a; };
    struct Derived : Base { int b; };

    auto foo = Derived();

    std::cout << foo.a << " " << foo.b;
}

I get this output:

-858993460 -858993460

But I expected:

0 0

Why is foo not zero-initialized?

user703016
  • 37,307
  • 8
  • 87
  • 112

2 Answers2

4

Should be initialized to zero, looks like MSVC bug. Since actually your code is like this

Derived foo{Derived()};

then copy/move constructor will be called on temporary object initialized with ().

n3376 8.5/10

An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.

n3376 8.5/7

To value-initialize an object of type T means:

if T is a (possibly cv-qualified) non-union class type without a user-provided or deleted default construc- tor, then the object is zero-initialized and, if T has a non-trivial default constructor, default-initialized;

n3376 8.5/5

To zero-initialize an object or reference of type T means:

if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits;

Community
  • 1
  • 1
ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • 1
    Actually it's the same as `Derived foo( (Derived()) );`. Without the extra parentheses, you hit the most embarrassing parse problem (and declare a function). – James Kanze Jan 21 '15 at 11:35
  • 1
    Wow, I would have lost 100 Dollars here easily. Did the "empty-parentheses-mean-value-initialization" rule always exist or has it been introduced with auto and braces? And I tried with VS 2013 vs gcc 4.9.2; VS does not initialize the struct, gcc does. – Peter - Reinstate Monica Jan 21 '15 at 12:04
  • I'd also be interested in whether indeed a "copy/move constructor will be called on temporary object". I'd have thought that there will always be just one object which is directly initialized, along the lines of `int i=0;` – Peter - Reinstate Monica Jan 21 '15 at 12:07
  • @PeterSchneider this rule was before C++11. It's not direct-initialization, it's copy initialization, but compiler can (and will) optimize it. – ForEveR Jan 21 '15 at 12:09
0

Your structs have no constructors, so default one are created.

Default constructor of a struct will call default constructor for each of memebers.

Default constructor of int doesn't initialize it. So int memeber will contain random data.

Add constructors to your structs and initialize memebers. Like this:

struct Base
{
    Base(): a(0) {}
    int a;
};
Michał Walenciak
  • 4,257
  • 4
  • 33
  • 61
  • OP asks _why_ it happens, not how to solve it. – HolyBlackCat Jan 21 '15 at 11:36
  • @HolyBlackCat I thought this post explains the "why" nicely. The question is whether it is correct (I thought it is until I read ForEverR's post). So is it?? – Peter - Reinstate Monica Jan 21 '15 at 11:49
  • I think it's not. if I remember correctly, If you don't ask for default constructor explicitly when you initialize a variable of struct type (if this struct have fields only with primitive types (or another similar structs) and don't have user-provided constructor that initializes these fields), then fields are not 0-initialized. See this: http://ideone.com/SkHTxi It prints garbage. Replace `Derived;` with `Derived();` at end of 9th line and it will print `0`s. – HolyBlackCat Jan 21 '15 at 11:59
  • Which means that Michał is wrong, as is VC (the workaround would work though). – Peter - Reinstate Monica Jan 21 '15 at 12:33