views:

403

answers:

2

I originally wrote some code like this:

class Foo
{
public:
  Foo() : m_buffer()
    {}

private:
  char   m_buffer[1024];
};

Someone who is smarter than me said that having the m_buffer() initializer would zero out the memory. My intention was to leave the memory uninitialized. I didn't have time to discuss it further, but it piqued my curiosity.

Previously, I had thought it was wise to always list each member in the initializer list.

Could someone please describe this behavior further?

1) Why does the empty-paren initializer fill in memory?

2) Does it only hold for POD datatypes? I heard that it was so, but don't have the standard handy.

Thanks

A: 

Previously, I had thought it was wise to always list each member in the initializer list.

This is to make sure all the members are initialized.

To solve your task simply remove m_buffer from the initializer list.

template <typename T>
struct C
{
    C():
        buff(),
        var(),
        object()
    {
    }
    T buff[128];
    T var;
    std::string object;
};

Whatever T type is using T() is go for default constructor. For int, chars, etc it is 0, for arrays it is {T()}. And for classes it is simply their default constructor.

Mykola Golubyev
+10  A: 

If you have a member initialized like that, it will be value-initialized. That is also true for PODs. For a struct, every member is value-initialized that way, and for an array, every element of it is value-initialized.

Value-initialization for a scalar type like pointer or integer you will have it inialized to 0 converted to the right type. So you will get null pointers or false or whatever type you have concretely.

Note that the rule changed subtly from C++98 to C++03 (what we have right now), which can have surprising effects. C++98 didn't have that value-initialization. It said default initialization happens, which for a non-POD type always meant it's default constructor invokes. But value-initialization in C++03 has special meaning if there is no user-declared constructor: Every element is value-initialized then.

Here is the difference:

struct A { int c; ~A() { } }; // non-POD, but no user declared ctor
struct B { A a; B():a(){ } } b;

Now, in C++03, you will be guaranteed that b.a.c is zero. While in C++98, b.a.c will have some indeterminated value.

Johannes Schaub - litb
value-initialization led me to this boost site: http://www.boost.org/doc/libs/1_38_0/libs/utility/value_init.htm#valueinitApparently some compilers get value-initialization wrong, leaving things uninitialized. Still good to know what the standard is.
jw
I think you have your 89 and 98 mixed ?
jw
oh thanks. i'll fix it asap
Johannes Schaub - litb
+1. My GOD initialisation in C++ is a mess. :(
j_random_hacker