C++ – Initialization

Initialization of variables/objects in C++ can often be a reason for confusion.

I sometimes find it hard to reason whether a variable/object has been initialized or not and when it has indeed been initialized, whether it contains an indeterminate value or not. There are numerous, often confusing rules concerning initialization of variables/objects in C++. It is important to get a good grasp of these rules if you are to be a serious C++ programmer. To add to the confusion, the newer versions of the language have made further changes to the initialization rules.

Please know that a compiler performs initialization only when the variables/objects in question are defined without an explicit initializer. Even before trying to understand the different initialization rules, it is important to know some of the properties that every variable in C++ possesses. These are scope, duration and linkage. I strongly recommend you to go through this article to get a better understanding of these properties.

Variables with static storage duration and thread storage duration are zero initialized at first. This means that an integer variable or a character variable gets a value = 0, a double or a float gets a value = 0.0 and a pointer is initialized to null.  Variables with automatic storage duration  and dynamic storage duration are never zero initialized.

All user defined objects are default initialized, ie, their default constructors are called. If an object does not have a default constructor, it is a compile time error.

Until C++ 03, initialization was not consistent and led to problems like the one commonly referred to as the Most Vexing Parse.

#include <iostream>
class B{
public:
int a;
B():a(1){}
};
class A{
public:
B b;
A(B b):b(b){}
};
int main(){
A obj1(B());
std::cout<< obj1.b.a;
// This might be a compiler error because obj1 gets
// interpreted as a declaration of a method.
A obj2( (B()) );
std::cout<< obj2.b.a;
// With the extra set of parenthesis, this is correctly
// interpreted as the creation of an object of class A;
}
view raw initialization1.cpp hosted with ❤ by GitHub

C++ 11 has introduced a new form of consistent initialization called as uniform initialization or list initialization. In this type of initialization , pretty much any object can be initialized using curly braces. ({}).

#include <vector>
class B{};
class A{
B b;
public:
A(B b):b(b){}
};
int main(){
A a{B()}; // There is no ambiguity here.
int var1{}; // Zero-initialized to 0;
char* var2{};// Zero-initialized to nullptr;
std::vector v1{}; // Each member is zero-initialized
std::vector v2{1,2,3}; // Vector is initialized with
// 3 elements 1,2 and 3.
}
view raw initialization2.cpp hosted with ❤ by GitHub

Aggregate initialization is a type of list initialization but works on aggregates. Note that an aggregate is an array type or a POD class type.

struct POD{
int a;
float b;
char c;
};
int main(){
POD pod{1,2,'c'}; // aggregate initialization
int a[5] = {1,2,3,4,5}; //aggregate initialization
}
view raw initialization3.cpp hosted with ❤ by GitHub

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s