Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

in c++11, can you always (safely) replace a memset() initialization with an empty initializer?

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?

like image 672
MikeTusar Avatar asked Aug 17 '13 02:08

MikeTusar


2 Answers

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.

like image 103
Dietmar Kühl Avatar answered Nov 02 '22 22:11

Dietmar Kühl


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.

like image 45
Saksham Avatar answered Nov 02 '22 23:11

Saksham