Search code examples
c++initializationvalue-initialization

C++ object initialization with copy-list-initializer


// Example program
#include <iostream>
#include <string>

class T{
public:   
    int x, y;
    T(){
        std::cout << "T() constr called..." << std::endl;
    };
    T(int x, int y):x(x),y(y){
        std::cout << "T(x,y) constr called..." << std::endl;
    }
    
    void inspect(){
        std::cout << "T.x: " << this->x << std::endl;
        std::cout << "T.y: " << this->y << std::endl;
    }
};

int main()
{
    T t1(5,6);
    t1.inspect();
    
    std::cout << std::endl;
    
    T t2 = {};
    t2.inspect();
}

I am getting the following result:

T(x,y) constr called...
T.x: 5
T.y: 6

T() constr called...
T.x: 208787120
T.y: 31385

The members of t2 instance were not zero initialized (what I wanted to achieve). Do I understand it correctly, that if I have a constructor defined, it will not perform a zero initialization? (I know how to achieve initialization to zero using explicit default values. The problem is why I am not able to do it using the init-list)

List initialization

Otherwise, if the braced-init-list is empty and T is a class type with a default constructor, value-initialization is performed.

Value-initialization

In all cases, if the empty pair of braces {} is used and T is an aggregate type, aggregate-initialization is performed instead of value-initialization.

Aggregate-initialization (it seems this is not my case and therefore it is not initializing members to zero)

An aggregate is one of the following types:

  • class type (typically, struct or union), that has
    • no user-declared constructors

What would be the simplest and less error-prone modification of legacy code, where I need to solve issues where some class members are used before they are initialized?


Solution

  • Do I understand it correctly, that if I have a constructor defined, it will not perform a zero initialization?

    Yes.

    Note that T is not an aggregate because it contains user-provided constructors. As the effect of value initialization:

    1. if T is a class type with no default constructor or with a user-provided or deleted default constructor, the object is default-initialized;

    2. if T is a class type with a default constructor that is neither user-provided nor deleted (that is, it may be a class with an implicitly-defined or defaulted default constructor), the object is zero-initialized and then it is default-initialized if it has a non-trivial default constructor;

    T contains a user-provided default constructor, then #1 (but not #2 performing zero-initialization firstly) is applied.

    In default initialization, the user-provided default constructor is used to initialize the object. The default constructor doesn't perform initialization on data members, they are initialized to indeterminate values.