How to initialize member-struct in initializer list of C++ class?

I have the following class definitions in c++:

struct Foo {
  int x;
  char array[24];
  short* y;
};

class Bar {
  Bar();

  int x;
  Foo foo;
};

and would like to initialize the "foo" struct (with all its members) to zero in the initializer of the Bar class. Can this be done this way:

Bar::Bar()
  : foo(),
    x(8) {
}

... ?

Or what exactly does the foo(x) do in the initializer list?

Or is the struct even initialized automatically to zero from the compiler?


First of all, you should (must !) read this c++ faq regarding POD and aggregates. In your case, Foo is indeed a POD class and foo() is a value initialization :

To value-initialize an object of type T means:

  • if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor
    for T is called (and the initialization is ill-formed if T has no accessible default constructor);
  • if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;
  • if T is an array type, then each element is value-initialized;
  • otherwise, the object is zero-initialized

So yes, foo will be zero-initialized. Note that if you removed this initialization from Bar constructor, foo would only be default-initialized :

If no initializer is specified for an object, and the object is of (possibly cv-qualified) non-POD class type (or array thereof), the object shall be default-initialized; if the object is of const-qualified type, the underlying class type shall have a user-declared default constructor. Otherwise, if no initializer is specified for a nonstatic object, the object and its subobjects, if any, have an indeterminate initial value;


In standard C++ you need to make a ctor for Foo.

struct Foo {

  Foo(int const a, std::initializer_list<char> const b, short* c)
    : x(a), y(c) {
    assert(b.size() >= 24, "err");
    std::copy(b.begin(), b.begin() + 24, array);
  }

  ~Foo() { delete y; }

  int x;
  char array[24];
  short* y;
};

class Bar {

  Bar() : x(5), foo(5, {'a', 'b', ..., 'y', 'z'},
    new short(5)) { }

  private:

  int x;
  Foo foo;
};

In C++0x you may use uniform initialization list, but still you need dtor for Foo:

class Bar {

  Bar() : x(5), foo{5, new char[24]{'a', 'b', ..., 'y', 'z'},
    new short(5)} { }
  ~Bar() { delete[] foo.array; delete foo.y;}
  }
  private:

  int x;
  Foo foo;
};

To default initialize foo (as Bar() : foo(), x(8) { }) you need to give Foo a default ctor.