Default, value and zero initialization mess

后端 未结 3 851
广开言路
广开言路 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 02:57

    C++14 specifies initialization of objects created with new in [expr.new]/17 ([expr.new]/15 in C++11, and the note wasn't a note but normative text back then):

    A new-expression that creates an object of type T initializes that object as follows:

    • If the new-initializer is omitted, the object is default-initialized (8.5). [ Note: If no initialization is performed, the object has an indeterminate value. — end note ]
    • Otherwise, the new-initializer is interpreted according to the initialization rules of 8.5 for direct-initialization.

    Default-initialization is defined in [dcl.init]/7 (/6 in C++11, and the wording itself has the same effect):

    To default-initialize an object of type T means:

    • if T is a (possibly cv-qualified) class type (Clause 9), the default constructor (12.1) for T is called (and the initialization is ill-formed if T has no default constructor or overload resolution (13.3) results in an ambiguity or in a function that is deleted or inaccessible from the context of the initialization);
    • if T is an array type, each element is default-initialized;
    • otherwise, no initialization is performed.

    Thus

    • new A solely causes As default constructor to be called, which does not initialize m. Indeterminate value. Should be the same for new B.
    • new A() is interpreted according to [dcl.init]/11 (/10 in C++11):

      An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.

      And now consider [dcl.init]/8 (/7 in C++11†):

      To value-initialize an object of type T means:

      • if T is a (possibly cv-qualified) class type (Clause 9) with either no default constructor (12.1) 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;
      • if T is an array type, then each element is value-initialized;
      • otherwise, the object is zero-initialized.

      Hence new A() will zero-initialize m. And this should be equivalent for A and B.

    • new C and new C() will default-initialize the object again, since the first bullet point from the last quote applies (C has a user-provided default constructor!). But, clearly, now m is initialized in the constructor in both cases.


    † Well, this paragraph has slightly different wording in C++11, which does not alter the result:

    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 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.

提交回复
热议问题