Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Zero-Initialization

I'm having trouble understanding when and why exactly a member in my class is zero-initialized according to http://en.cppreference.com/w/cpp/language/zero_initialization.

Consider the following test program:

#include <iostream> #include <stdio.h>  class MyTest { private:     const static unsigned int dimension = 8;     void (* myFunctions [dimension])();  public:      MyTest() {}      void print() {          for(unsigned int i=0; i < MyTest::dimension; i++) {             printf("myFunctions[%d] = %p\n", i, this->myFunctions[i]);         }        } };   int main() {     //We declare and initialize an object on the stack      MyTest testObj = {};     testObj.print();      return 0; } 

I am declaring a class to have an array of 8 function pointers of the signature "void functionname()". When I declare and initialize an object of the class in main as MyTest testObj = {}; or MyTest testObj;, I expected it to be zero-initialized, i.e. all pointers are null pointers.

However, compiling with g++ 5.3.0 on my Windows 10 machine with g++ -m32 -o test -std=c++14 test.cpp && test machine gives the output:

myFunctions[0] = 76dd6b7d myFunctions[1] = 00401950 myFunctions[2] = 0061ff94 myFunctions[3] = 004019ab myFunctions[4] = 00401950 myFunctions[5] = 00000000 myFunctions[6] = 003cf000 myFunctions[7] = 00400080 

Which look like un-initialized values from the stack..

If I move the declaration of the object outside of main (as a global variable), it prints all zeroes again.

If I have understood cppreference correctly, this is because I have a variariable with static storage duration, and is thus zero-initialized. It initializes my class type by zero-initializing all non-static data members of my class (i.e., the myFunctions) array. An array is initialized by zero-initializing every element of it, which, in my function pointer case, is a null pointer.

Why does it not zero-initialize my object the stack when I declare it with MyTest testObj = {};?

like image 665
Maximilian Gerhardt Avatar asked Feb 15 '18 14:02

Maximilian Gerhardt


People also ask

Does C initialize variables to 0?

In C programming language, the variables should be declared before a value is assigned to it. In an array, if fewer elements are used than the specified size of the array, then the remaining elements will be set by default to 0.

Are arrays in C initialized to 0?

Please note that the global arrays will be initialized with their default values when no initializer is specified. For instance, the integer arrays are initialized by 0 . Double and float values will be initialized with 0.0 . For char arrays, the default value is '\0' .

How do you initialize an array to zero?

Using Initializer List. int arr[] = { 1, 1, 1, 1, 1 }; The array will be initialized to 0 if we provide the empty initializer list or just specify 0 in the initializer list.

What is initialization in C?

Initialization is the process of locating and using the defined values for variable data that is used by a computer program. For example, an operating system or application program is installed with default or user-specified values that determine certain aspects of how the system or program is to function.


1 Answers

The following

MyTest testObj = {}; 

is not zero-initialization for MyTest, but is simply calling its default constructor. The cppreference page explains why (emphasis mine):

As part of value-initialization sequence for non-class types and for members of value-initialized class types that have no constructors, including value initialization of elements of aggregates for which no initializers are provided.

MyTest is a class type, and a has a constructor.


Defining the constructor with

MyTest() = default; 

will instead zero-initialize the object.

Relevant Standard quotes (emphasis mine) below.

From [dcl.init#8]:

To value-initialize an object of type T means:

  • if T is a (possibly cv-qualified) class type with either no default constructor ([class.ctor]) or a default constructor that is user-provided or deleted, then the object is default-initialized;

  • if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;

  • ...

From [dcl.init.list]:

List-initialization of an object or reference of type T is defined as follows:

  • ...

  • Otherwise, if the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.

like image 104
Vittorio Romeo Avatar answered Sep 21 '22 13:09

Vittorio Romeo