10
votes

I frequently come across POD structs in code that are manually zero-initialized with memset like so:

struct foo;
memset(&foo, 0, sizeof(foo));

I checked the C++11 standard and it says: "An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized." Followed by: "To value-initialize a [pod struct] of type T means ... the object is zero-initialized."

So... does this mean you can always safely condense the above code to just the following:

struct foo{};

And have a guaranteed initialized struct as if you had called memset(&foo, 0, ...)?


If so, then generally speaking, can you safely initialize anything with empty initializers like so:

SomeUnknownType foo{};  // will 'foo' be completely "set" to known values?

I know this wasn't always possible in C++03 (before uniform initialization syntax) but is it possible now in C++11 for any type?

2
check this thread : stackoverflow.com/questions/620137/… General answer is yes.CS Pei
Be aware that MSVC has never properly supported value initialization and will fail in some contexts. Microsoft does not seem to be interested in fixing the bug.Casey
@Casey: That's a pretty serious bug, I wonder if it's been fixed in the latest VS. Fortunately, I use gcc and clang (which seem to care about being standards compliant) and my code does not have to be portable to other compilers or even older versions of gcc or clang.MikeTusar

2 Answers

10
votes

You can certainly initialize any standard layout type using empty parenthesis and get it zero initialized. Once you add constructors into the picture, this isn't necessarily true, unfortunately:

struct foo {
    int f;
};
struct bar {
    int b;
    bar() {}
};

foo f{};
bar b{};

While f.f is zero initialized, b.b is uninitialized. However, there isn't anything you can do about bar because you can't memset() it either. It needs to be fixed.

3
votes

Memset will initialize it to 0 but empty parenthesis will value initialze your object(there is a difference).

Quoting from the standard:

To value-initialize an object of type T means:

  • if T is a class type with a user-declared constructor, then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

Also, doing struct foo{}; is safe and it takes care of not reseting the virtual table pointer.

But doing memset(&foo, 0, sizeof(foo)); in case of virtual functions is really really bad as it resets the pointer to the virtual table.