How to Make a C++ Struct Value-Initialize All Pod Member Variables

Is there a way to make a C++ struct value-initialize all POD member variables?

The cleanest way would be to write the auto-initialzed template class initialized<T>:

EDIT: I realize now it can be made even more flexible by allowing you to declare initialized<Struct>. This means that you can declare initialization without modifying the original Struct. The default initialization 'T()' was inspired on Prasoons answer.

template<class T>  
struct initialized
{
public:

initialized()
{ value = T(); }

initialized(T t)
{ value = t; }

initialized(const initialized<T>& x)
{ value = x.value; }

T* operator &() { return &value; }

operator T&() { return value; }

private:
T value;
};

struct PodStruct
{
std::string String;
int Int;
};

struct GlorifiedPodStruct
{
std::string String;
initialized<int> Int;
};

void Test()
{
GlorifiedPodStruct s;
s.Int = 1;
int b = s.Int;
int * pointer = &s.Int;

initialized<PodStruct> s2;
}

This compiles, but may need more conversion operators, handling of keywords like volatile, etc. But you get the idea.

C++ Structure Initialization

If you want to make it clear what each initializer value is, just split it up on multiple lines, with a comment on each:

address temp_addres = {
0, // street_no
nullptr, // street_name
"Hamilton", // city
"Ontario", // prov
nullptr, // postal_code
};

Initializing member variables of a struct in c++

Not by default (unless it's a variable of static storage - that is, a static or global variable).

There are a few ways to initialize a struct of this kind to "zeros":

A a = { 0.0, 0.0 };
A a = { };

A a = A();

or if you have a C++11 compatible compiler:

A a{0.0, 0.0};
A a{}

or add a constructor to the struct definition:

struct A {
double a;
double b;
A() : a(0.0), b(0.0) {}
};

Convenient C++ struct initialisation

Designated initializes will be supported in c++2a, but you don't have to wait, because they are officialy supported by GCC, Clang and MSVC.

#include <iostream>
#include <filesystem>

struct hello_world {
const char* hello;
const char* world;
};

int main ()
{
hello_world hw = {
.hello = "hello, ",
.world = "world!"
};

std::cout << hw.hello << hw.world << std::endl;
return 0;
}

GCC Demo
MSVC Demo

Update 2021

As @Code Doggo noted, anyone who is using Visual Studio 2019 will need to set /std:c++latest  for the "C++ Language Standard" field contained under Configuration Properties -> C/C++ -> Language.

Proper way to initialize C++ structs

In C++ classes/structs are identical (in terms of initialization).

A non POD struct may as well have a constructor so it can initialize members.

If your struct is a POD then you can use an initializer.

struct C
{
int x;
int y;
};

C c = {0}; // Zero initialize POD

Alternatively you can use the default constructor.

C  c = C();      // Zero initialize using default constructor
C c{}; // Latest versions accept this syntax.
C* c = new C(); // Zero initialize a dynamically allocated object.

// Note the difference between the above and the initialize version of the constructor.
// Note: All above comments apply to POD structures.
C c; // members are random
C* c = new C; // members are random (more officially undefined).

I believe valgrind is complaining because that is how C++ used to work. (I am not exactly sure when C++ was upgraded with the zero initialization default construction). Your best bet is to add a constructor that initializes the object (structs are allowed constructors).

As a side note:

A lot of beginners try to value init:

C c(); // Unfortunately this is not a variable declaration.
C c{}; // This syntax was added to overcome this confusion.

// The correct way to do this is:
C c = C();

A quick search for the "Most Vexing Parse" will provide a better explanation than I can.

Are members of a C++ struct initialized to 0 by default?

They are not null if you don't initialize the struct.

Snapshot s; // receives no initialization
Snapshot s = {}; // value initializes all members

The second will make all members zero, the first leaves them at unspecified values. Note that it is recursive:

struct Parent { Snapshot s; };
Parent p; // receives no initialization
Parent p = {}; // value initializes all members

The second will make p.s.{x,y} zero. You cannot use these aggregate initializer lists if you've got constructors in your struct. If that is the case, you will have to add proper initalization to those constructors

struct Snapshot {
int x;
double y;
Snapshot():x(0),y(0) { }
// other ctors / functions...
};

Will initialize both x and y to 0. Note that you can use x(), y() to initialize them disregarding of their type: That's then value initialization, and usually yields a proper initial value (0 for int, 0.0 for double, calling the default constructor for user defined types that have user declared constructors, ...). This is important especially if your struct is a template.

Initializing default values in a struct

Yes. bar.a and bar.b are set to true, but bar.c is undefined. However, certain compilers will set it to false.

See a live example here: struct demo

According to C++ standard Section 8.5.12:

if no initialization is performed, an
object with automatic or dynamic storage duration has indeterminate value

For primitive built-in data types (bool, char, wchar_t, short, int, long, float, double, long double), only global variables (all static storage variables) get default value of zero if they are not explicitly initialized.

If you don't really want undefined bar.c to start with, you should also initialize it like you did for bar.a and bar.b.

Value initialization and Non POD types

Visual Studio has known bugs in all current versions (2005, 2008, 2010) where it doesn't correctly implement value-initialization for non-POD types that don't have a user declared constructor.

By the language rules none of you asserts should fire but do exhibit the compiler issues. These are some of the bug reports, note that they are all closed or resolved as "Won't Fix".

http://connect.microsoft.com/VisualStudio/feedback/details/564268/c-value-initialization

http://connect.microsoft.com/VisualStudio/feedback/details/484295/vc-does-not-value-initialize-members-of-derived-classes-without-user-declared-constructor

http://connect.microsoft.com/VisualStudio/feedback/details/100744/value-initialization-in-new-expression



Related Topics



Leave a reply



Submit