Search code examples
c++arraysinitialization

Zero initialization of string and string array (C++)


According to https://en.cppreference.com/w/cpp/language/zero_initialization

enter image description here

In the example provided by the documentation:

std::string s; // is first zero-initialized to indeterminate value
               // then default-initialized to ""

Why does zero initialization occur to string s; if the syntax is for static T object;?

Why does zero initialization happen before default initialization and why are both allowed to happen?

The effects of zero initialization are:

  • If T is a scalar type, the object's initial value is the integral constant zero explicitly converted to T.
  • If T is an non-union class type, all base classes and non-static data members are zero-initialized, and all padding is initialized to zero bits. The constructors, if any, are ignored.
  • If T is a union type, the first non-static named data member is zero-initialized and all padding is initialized to zero bits.
  • If T is array type, each element is zero-initialized
  • If T is reference type, nothing is done.

What if I initialize string array[2] = {"Test1"};? I know that the array will contain "Test1" and empty string "".

But according to the above documentation,

If T is array type, each element is zero-initialized

The data type is string which is an object / reference type?

If T is reference type, nothing is done.

Nothing is done? I thought maybe a constructor would have been called. Surely an empty string is something?


Solution

  • (Unless otherwise specified, all declarations in this answer are assumed to be in namespace scope.)

    Why does zero initialization occur to string s; if the syntax is for static T object;?
    Why does zero initialization happen before default initialization and why are both allowed to happen?

    Variables with static storage duration are first zero-initialized at compile time, and then optionally dynamically initialized at runtime. static T object; declares an object of static storage duration. For a simple declaration like

    int x;
    

    The dynamic initialization is not performed. For a more sophisticated declaration like

    std::string s;
    

    Zero-initializing a string may result in an invalid string with a broken class invariant. Therefore, the dynamic initialization calls the default constructor to ensure that the object is valid.

    What if I initialize string array[2] = {"Test1"};? I know that the array will contain "Test1" and empty string "".

    First, at compile time, the two objects are zero-initialized, resulting in possible invalid state. Then, at runtime, the constructors are called (const char* constructor for the first object and default constructor for the second object), and the valid objects are constructed.

    The data type is string which is an object / reference type?

    std::string is an object type instead of a reference type.

    [For a reference type] Nothing is done? I thought maybe a constructor would have been called. Surely an empty string is something?

    A reference type is not considered an actual "object", so there is no point in specifying its zero-initialization semantics.