Take Charge and Initialize Your Own Data

nlike most other programming languages, C++ by default doesn’t initialize automatic variables. Consequently, uninitialized auto variables and aggregates have an indeterminate value.

Due to insufficient familiarity with the correct syntax of aggregate initialization, many programmers either misuse library functions such as memset() or forgo initialization altogether, thereby incurring unnecessary performance overhead, future maintenance problems, and potential bugs.

Properly initialize all POD (“Plain Old Data”) auto variables in your programs to ensure reliability and efficiency.

Step 1: Initialization of Fundamental Datatypes
Initialization of fundamental types such as int, bool, and double is simple. Just place an assignment operator followed by a proper initializer in the declaration. For example:

int main(){int stat=0;double salary=0.0;bool temp=false;employee *p=NULL;//}

Notice that each initializer is of the correct type. This isn’t really necessary since, as a special case, C++ allows you to use 0 as a universal initializer for fundamental types, including pointers, pointers to functions and even pointers to members. Therefore, you may initialize temp like this:

bool temp=0; // 0 is converted to 'false'

Likewise, you may initialize all pointer types like this:

employee *p=0; //converted to NULLvoid (*pfunc)(int)=0; //pointer to functionvoid (A::*pfunc)(int)=0; //pointer to member function

In fact, you are advised to use plain 0 instead of NULL in pointer initializations. This will save you the trouble of #including a special header.

Step 2: Array Initialization
Syntactically, initializations look like ordinary assignments. However, there are substantial differences between the two. Conceptually, an initialization takes place at compile time whereas an assignment takes place at runtime. More importantly, you are allowed to initialize an array or a an aggregate (I will discuss aggregates shortly) but you cant assign to them:

char name1[5]="John"; //OK, initializationchar name2[5];name2= "John"; //compilation error: assignment to an array

When initializing an array, you are allowed to use fewer initializers than the number of its elements (the opposite, however, is forbidden). It is guaranteed that the remaining elements are default-initialized in this case. For example, in the following expression, the array num has five elements but only the first three have explicit initializers:

int num[5]={0,1,2};

The elements num[4] and num[5] are automatically initialized to 0 in this case. Thus, to zero-initialize a large array you can provide a single initializer and let the compiler take care of the rest:

double results[500]={0.0}; //the remaining 499 elements                           // are initialized to 0.0 as well

This form has the same effect:

double results[500]={0};

Or, if you’re using a char array:

char URL[2048]={0}; //all elements are initialized to ''

Notice how cumbersome and error prone a memset() call looks in comparison:

#include char URL[2048];memset(URL, 0, 2048);

Not only do you need to #include a special header, this form also presents a serious maintenance problem if the size of the array changes in the future. Worse yet, programmers tend to confuse between the second and third arguments:

int arr[100];memset (arr, 100*sizeof(int), 0); //oops, meant (arr, 0, 100*sizeof(int))

This code compiles and links fine but at runtime the array elements will contain garbage values.

Step 3: Aggregate Initialization
In plain English, an aggregate is a POD struct, class or union, or an array of POD elements (including fundamental types). To initialize a POD struct, provide one or more initializers enclosed in curly braces. If there are fewer initializers than the number of members, the remaining members are default-initialized:

struct Person {  int age;  char name[20];  char address[100];  char occupation[50]; }; Person p={25, "Phileas Fogg", "Saville Row, W1 London"};

In this case, the elements of the array occupation are zero-initialized because no explicit initializer was provided for this member. Just as with arrays, you can easily zero initialize all the members of a struct like this:

Person p={0};

You’re probably wondering whether this initailization form would compiled if the first member weren’t a scalar type, say:

struct Book {  char title[200]; //array instead of a scalar type char author[200];  int page_count; }; 

Yes, it would:

Book b={0}; 

Remember that aggregate initialization rules are recursive: the initializer 0 is treated as the initializer of the first member of Book, which is an array. As previously noted, when an array’s initialization list contains fewer initializers than the number of its elements, the remaining elements are zero-initialized. The literal 0 first initializes the first element of the array title, letting the compiler zero-initialize all the remaining elements. Because the initialization list of b doesn’t provide explicit initializers for the rest of its members, these are zero-initialized as well.

Now suppose you want to declare an array of Book objects. The same form of initialization zero-initializes every element of the array:

Book arr[20] ={0};

Remember, it doesn’t matter if you change the definition of Book later, say by adding more data members to it, or if you change the size of the array. The ={0}; initializer ensures that every member is properly initialized.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin


Recent Articles: