9 Declarations [dcl.dcl]

9.4 Initializers [dcl.init]

9.4.1 General [dcl.init.general]

The process of initialization described in [dcl.init] applies to all initializations regardless of syntactic context, including the initialization of a function parameter ([expr.call]), the initialization of a return value ([stmt.return]), or when an initializer follows a declarator.
[Note 1: 
The rules in [dcl.init] apply even if the grammar permits only the brace-or-equal-initializer form of initializer in a given context.
— end note]
Except for objects declared with the constexpr specifier, for which see [dcl.constexpr], an initializer in the definition of a variable can consist of arbitrary expressions involving literals and previously declared variables and functions, regardless of the variable's storage duration.
[Example 1: int f(int); int a = 2; int b = f(a); int c(b); — end example]
[Note 2: 
Default arguments are more restricted; see [dcl.fct.default].
— end note]
[Note 3: 
The order of initialization of variables with static storage duration is described in [basic.start] and [stmt.dcl].
— end note]
A declaration D of a variable with linkage shall not have an initializer if D inhabits a block scope.
To zero-initialize an object or reference of type T means:
  • if T is a scalar type ([basic.types.general]), the object is initialized to the value obtained by converting the integer literal 0 (zero) to T;78
  • if T is a (possibly cv-qualified) non-union class type, its padding bits ([basic.types.general]) are initialized to zero bits and each non-static data member, each non-virtual base class subobject, and, if the object is not a base class subobject, each virtual base class subobject is zero-initialized;
  • if T is a (possibly cv-qualified) union type, its padding bits ([basic.types.general]) are initialized to zero bits and the object's first non-static named data member is zero-initialized;
  • if T is an array type, each element is zero-initialized;
  • if T is a reference type, no initialization is performed.
To default-initialize an object of type T means:
  • If T is a (possibly cv-qualified) class type ([class]), constructors are considered.
    The applicable constructors are enumerated ([over.match.ctor]), and the best one for the initializer () is chosen through overload resolution ([over.match]).
    The constructor thus selected is called, with an empty argument list, to initialize the object.
  • If T is an array type, the semantic constraints of default-initializing a hypothetical element shall be met and each element is default-initialized.
  • Otherwise, no initialization is performed.
A class type T is const-default-constructible if default-initialization of T would invoke a user-provided constructor of T (not inherited from a base class) or if
  • each direct non-variant non-static data member M of T has a default member initializer or, if M is of class type X (or array thereof), X is const-default-constructible,
  • if T is a union with at least one non-static data member, exactly one variant member has a default member initializer,
  • if T is not a union, for each anonymous union member with at least one non-static data member (if any), exactly one non-static data member has a default member initializer, and
  • each potentially constructed base class of T is const-default-constructible.
If a program calls for the default-initialization of an object of a const-qualified type T, T shall be a const-default-constructible class type or array thereof.
To value-initialize an object of type T means:
  • If T is a (possibly cv-qualified) class type ([class]), then let C be the constructor selected to default-initialize the object, if any.
    If C is not user-provided, the object is first zero-initialized.
    In all cases, the object is then default-initialized.
  • If T is an array type, the semantic constraints of value-initializing a hypothetical element shall be met and each element is value-initialized.
  • Otherwise, the object is zero-initialized.
A program that calls for default-initialization or value-initialization of an entity of reference type is ill-formed.
[Note 4: 
For every object of static storage duration, static initialization ([basic.start.static]) is performed at program startup before any other initialization takes place.
In some cases, additional initialization is done later.
— end note]
If no initializer is specified for an object, the object is default-initialized.
If the entity being initialized does not have class or array type, the expression-list in a parenthesized initializer shall be a single expression.
The initialization that occurs in the = form of a brace-or-equal-initializer or condition ([stmt.select]), as well as in argument passing, function return, throwing an exception ([except.throw]), handling an exception ([except.handle]), and aggregate member initialization other than by a designated-initializer-clause ([dcl.init.aggr]), is called copy-initialization.
[Note 5: 
Copy-initialization can invoke a move ([class.copy.ctor]).
— end note]
The initialization that occurs is called direct-initialization.
The semantics of initializers are as follows.
The destination type is the cv-unqualified type of the object or reference being initialized and the source type is the type of the initializer expression.
If the initializer is not a single (possibly parenthesized) expression, the source type is not defined.
  • If the initializer is a (non-parenthesized) braced-init-list or is = braced-init-list, the object or reference is list-initialized ([dcl.init.list]).
  • If the destination type is a reference type, see [dcl.init.ref].
  • If the destination type is an array of characters, an array of char8_t, an array of char16_t, an array of char32_t, or an array of wchar_t, and the initializer is a string-literal, see [dcl.init.string].
  • If the initializer is (), the object is value-initialized.
    [Note 6: 
    Since () is not permitted by the syntax for initializer, X a(); is not the declaration of an object of class X, but the declaration of a function taking no arguments and returning an X.
    The form () can appear in certain other initialization contexts ([expr.new], [expr.type.conv], [class.base.init]).
    — end note]
  • Otherwise, if the destination type is an array, the object is initialized as follows.
    The initializer shall be of the form ( expression-list ).
    Let , , be the elements of the expression-list.
    If the destination type is an array of unknown bound, it is defined as having k elements.
    Let n denote the array size after this potential adjustment.
    If k is greater than n, the program is ill-formed.
    Otherwise, the array element is copy-initialized with for each 1  ≤ i  ≤ k, and value-initialized for each .
    For each , every value computation and side effect associated with the initialization of the element of the array is sequenced before those associated with the initialization of the element.
  • Otherwise, if the destination type is a class type:
    • If the initializer expression is a prvalue and the cv-unqualified version of the source type is the same as the destination type, the initializer expression is used to initialize the destination object.
      [Example 2: 
      T x = T(T(T())); value-initializes x.
      — end example]
    • Otherwise, if the initialization is direct-initialization, or if it is copy-initialization where the cv-unqualified version of the source type is the same as or is derived from the class of the destination type, constructors are considered.
      The applicable constructors are enumerated ([over.match.ctor]), and the best one is chosen through overload resolution ([over.match]).
      Then:
      • If overload resolution is successful, the selected constructor is called to initialize the object, with the initializer expression or expression-list as its argument(s).
      • Otherwise, if no constructor is viable, the destination type is an aggregate class, and the initializer is a parenthesized expression-list, the object is initialized as follows.
        Let , , be the elements of the aggregate ([dcl.init.aggr]).
        Let , , be the elements of the expression-list.
        If k is greater than n, the program is ill-formed.
        The element is copy-initialized with for 1  ≤ i  ≤ k.
        The remaining elements are initialized with their default member initializers, if any, and otherwise are value-initialized.
        For each , every value computation and side effect associated with the initialization of is sequenced before those associated with the initialization of .
        [Note 7: 
        By contrast with direct-list-initialization, narrowing conversions ([dcl.init.list]) can appear, designators are not permitted, a temporary object bound to a reference does not have its lifetime extended ([class.temporary]), and there is no brace elision.
        [Example 3: struct A { int a; int&& r; }; int f(); int n = 10; A a1{1, f()}; // OK, lifetime is extended A a2(1, f()); // well-formed, but dangling reference A a3{1.0, 1}; // error: narrowing conversion A a4(1.0, 1); // well-formed, but dangling reference A a5(1.0, std::move(n)); // OK — end example]
        — end note]
      • Otherwise, the initialization is ill-formed.
    • Otherwise (i.e., for the remaining copy-initialization cases), user-defined conversions that can convert from the source type to the destination type or (when a conversion function is used) to a derived class thereof are enumerated as described in [over.match.copy], and the best one is chosen through overload resolution ([over.match]).
      If the conversion cannot be done or is ambiguous, the initialization is ill-formed.
      The function selected is called with the initializer expression as its argument; if the function is a constructor, the call is a prvalue of the cv-unqualified version of the destination type whose result object is initialized by the constructor.
      The call is used to direct-initialize, according to the rules above, the object that is the destination of the copy-initialization.
  • Otherwise, if the source type is a (possibly cv-qualified) class type, conversion functions are considered.
    The applicable conversion functions are enumerated ([over.match.conv]), and the best one is chosen through overload resolution ([over.match]).
    The user-defined conversion so selected is called to convert the initializer expression into the object being initialized.
    If the conversion cannot be done or is ambiguous, the initialization is ill-formed.
  • Otherwise, if the initialization is direct-initialization, the source type is std​::​nullptr_t, and the destination type is bool, the initial value of the object being initialized is false.
  • Otherwise, the initial value of the object being initialized is the (possibly converted) value of the initializer expression.
    A standard conversion sequence ([conv]) is used to convert the initializer expression to a prvalue of the destination type; no user-defined conversions are considered.
    If the conversion cannot be done, the initialization is ill-formed.
    When initializing a bit-field with a value that it cannot represent, the resulting value of the bit-field is implementation-defined.
    [Note 8: 
    An expression of type “cv1 T” can initialize an object of type “cv2 T” independently of the cv-qualifiers cv1 and cv2.
    int a; const int b = a; int c = b; — end note]
An immediate invocation ([expr.const]) that is not evaluated where it appears ([dcl.fct.default], [class.mem.general]) is evaluated and checked for whether it is a constant expression at the point where the enclosing initializer is used in a function call, a constructor definition, or an aggregate initialization.
An initializer-clause followed by an ellipsis is a pack expansion ([temp.variadic]).
Initialization includes the evaluation of all subexpressions of each initializer-clause of the initializer (possibly nested within braced-init-lists) and the creation of any temporary objects for function arguments or return values ([class.temporary]).
If the initializer is a parenthesized expression-list, the expressions are evaluated in the order specified for function calls ([expr.call]).
The same identifier shall not appear in multiple designators of a designated-initializer-list.
An object whose initialization has completed is deemed to be constructed, even if the object is of non-class type or no constructor of the object's class is invoked for the initialization.
[Note 9: 
Such an object might have been value-initialized or initialized by aggregate initialization ([dcl.init.aggr]) or by an inherited constructor ([class.inhctor.init]).
— end note]
Destroying an object of class type invokes the destructor of the class.
Destroying a scalar type has no effect other than ending the lifetime of the object ([basic.life]).
Destroying an array destroys each element in reverse subscript order.
A declaration that specifies the initialization of a variable, whether from an explicit initializer or by default-initialization, is called the initializing declaration of that variable.
[Note 10: 
In most cases this is the defining declaration ([basic.def]) of the variable, but the initializing declaration of a non-inline static data member ([class.static.data]) can be the declaration within the class definition and not the definition (if any) outside it.
— end note]
78)78)
As specified in [conv.ptr], converting an integer literal whose value is 0 to a pointer type results in a null pointer value.