Default, value and zero initialization mess

后端 未结 3 854
广开言路
广开言路 2020-11-28 02:38

I am very confused about value- & default- & zero-initialization. and especially when they kick in for the different standards C++03 and C++11 (and

3条回答
  •  野性不改
    2020-11-28 03:10

    The following answer extends the answer https://stackoverflow.com/a/620402/977038 which would serve as a reference for C++ 98 and C++ 03

    Quoting the answer

    1. In C++1998 there are 2 types of initialization: zero and default
    2. In C++2003 a 3rd type of initialization, value initialization was added.

    C++11 (In reference to n3242)

    Initializers

    8.5 Initializers [dcl.init] specifies that a variable POD or non POD can be initialized either as brace-or-equal-initializer which can either be braced-init-list or initializer-clause aggregately referred to as brace-or-equal-initializer or using ( expression-list ). Previous to C++11, only (expression-list) or initializer-clause was supported though initializer-clause was more restricted then what we have in C++11. In C++11, initializer-clause now supports braced-init-list apart from assignment-expression as was in C++03. The following grammar summarizes the new supported clause, where the part is bold is newly added in the C++11 standard.

    initializer:
        brace-or-equal-initializer
        ( expression-list )
    brace-or-equal-initializer:
        = initializer-clause
        braced-init-list
    initializer-clause:
        assignment-expression
        braced-init-list
    initializer-list:
        initializer-clause ...opt
        initializer-list , initializer-clause ...opt**
    braced-init-list:
        { initializer-list ,opt }
        { }

    Initialization

    Like C++03, C++11 still supports three form of initialize


    Note

    The part highlighted in bold has been added in C++11 and the one that is striked out has been removed from C++11.

    1. Initializer Type:8.5.5 [dcl.init] _zero-initialize_

    Performed in the following cases

    • Objects with static or thread storage duration are zero-initialized
    • If there are fewer initializers than there are array elements, each element not explicitly initialized shall be zero-initialized
    • During value-initialize, if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized.

    To zero-initialize an object or reference of type T means:

    • if T is a scalar type (3.9), the object is set to the value 0 (zero), taken as an integral constant expression, converted to T;
    • if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits;
    • if T is a (possibly cv-qualified) union type, the object’s first non-static named data member is zero initialized and padding is initialized to zero bits;
    • if T is an array type, each element is zero-initialized;
    • if T is a reference type, no initialization is performed.

    2. Initializer Type: 8.5.6 [dcl.init] _default-initialize_

    Performed in the following cases

    • If the new-initializer is omitted, the object is default-initialized; if no initialization is performed, the object has indeterminate value.
    • If no initializer is specified for an object, the object is default-initialized, except for Objects with static or thread storage duration
    • When a base class or a non-static data member is not mentioned in a constructor initializer list and that constructor is called.

    To default-initialize an object of type T means:

    • if T is a (possibly cv-qualified) non-POD class type (Clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
    • if T is an array type, each element is default-initialized;
    • otherwise, no initialization is performed.

    Note Until C++11, only non-POD class types with automatic storage duration were considered to be default-initialized when no initializer is used.


    3. Initializer Type: 8.5.7 [dcl.init] _value-initialize_

    1. When an object(nameless temporary, named variable, dynamic storage duration or non-static data member) whose initializer is an empty set of parentheses, i.e., () or braces {}

    To value-initialize an object of type T means:

    • if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
    • if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then every non-static data member and base-class component of T is value-initialized; then the object is zero-initialized and, if T’s implicitly-declared default constructor is non-trivial, that constructor is called.
    • if T is an array type, then each element is value-initialized;
    • otherwise, the object is zero-initialized.

    So to summarize

    Note The relevant quotation from the standard is highlighted in bold

    • new A : default-initializes (leaves A::m uninitialized)
    • new A() : Zero-initialize A, as the value initialized candidate does not have a user-provided or deleted default constructor. if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized and, if T’s implicitly-declared default constructor is non-trivial, that constructor is called.
    • new B : default-initializes (leaves B::m uninitialized)
    • new B() : value-initializes B which zero-initializes all fields; if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the default constructor for T is called
    • new C : default-initializes C, which calls the default ctor. if T is a (possibly cv-qualified) class type (Clause 9), the default constructor for T is called, Moreover If the new-initializer is omitted, the object is default-initialized
    • new C() : value-initializes C, which calls the default ctor. if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the default constructor for T is called. Moreover, An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized

提交回复
热议问题