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
Does Std::Cout Have a Return Value
Can a Variable Be Declared Both Static and Extern
Oracle Oci, Bind Variables, and Queries Like Id in (1, 2, 3)
Using Boost Adaptors with C++11 Lambdas
Efficient Multiply/Divide of Two 128-Bit Integers on X86 (No 64-Bit)
Calling Base Class Definition of Virtual Member Function with Function Pointer
Unique_Ptr and Openssl's Stack_Of(X509)*
Std::Vector Capacity After Copying
Enumdisplaydevices VS Wmi Win32_Desktopmonitor, How to Detect Active Monitors
How Disastrous Is Integer Overflow in C++
How to Print a String to the Console at Specific Coordinates in C++
Is Using Unsigned Integer Overflow Good Practice
How to Not Wait for a System() Command to Finish? (In C)
Pointer Array and Sizeof Confusion