Files
cppdraft_translate/cppdraft/dcl/init/general.md
2025-10-25 03:02:53 +03:00

27 KiB
Raw Blame History

[dcl.init.general]

9 Declarations [dcl]

9.5 Initializers [dcl.init]

9.5.1 General [dcl.init.general]

1

#

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.

initializer:
brace-or-equal-initializer
( expression-list )

brace-or-equal-initializer:
= initializer-clause
braced-init-list

initializer-clause:
assignment-expression
braced-init-list

braced-init-list:
{ initializer-list ,opt }
{ designated-initializer-list ,opt }
{ }

initializer-list:
initializer-clause ...opt
initializer-list , initializer-clause ...opt

designated-initializer-list:
designated-initializer-clause
designated-initializer-list , designated-initializer-clause

designated-initializer-clause:
designator brace-or-equal-initializer

designator:
. identifier

expr-or-braced-init-list:
expression
braced-init-list

[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]

2

#

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]

3

#

[Note 2:

Default arguments are more restricted; see [dcl.fct.default].

— end note]

4

#

[Note 3:

The order of initialization of variables with static storage duration is described in [basic.start] and [stmt.dcl].

— end note]

5

#

A declaration D of a variable with linkage shall not have an initializer if D inhabits a block scope.

6

#

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

if T is std::meta::info, the object is initialized to a null reflection value;

if T is any other scalar type ([basic.types.general]), the object is initialized to the value obtained by converting the integer literal 0 (zero) to T;78

ifT 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;

ifT 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;

ifT is an array type, each element is zero-initialized;

ifT is a reference type, no initialization is performed.

7

#

Todefault-initialize an object of typeT means:

  • (7.1)

    IfT is a (possibly cv-qualified) class type ([class]), constructors are considered. The applicable constructors are enumerated ([over.match.ctor]), and the best one for theinitializer () is chosen through overload resolution ([over.match]). The constructor thus selected is called, with an empty argument list, to initialize the object.

  • (7.2)

    IfT is an array type, the semantic constraints of default-initializing a hypothetical element shall be met and each element is default-initialized.

  • (7.3)

    If T is std::meta::info, the object is zero-initialized.

  • (7.4)

    Otherwise, no initialization is performed.

8

#

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 std::meta::
info or a const-default-constructible class type, or array thereof.

9

#

Tovalue-initialize an object of typeT means:

  • (9.1)

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

  • (9.2)

    IfT is an array type, the semantic constraints of value-initializing a hypothetical element shall be met and each element is value-initialized.

  • (9.3)

    Otherwise, the object is zero-initialized.

10

#

A program that calls for default-initialization or value-initialization of an entity of reference type is ill-formed.

11

#

[Note 4:

For every object with 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]

12

#

If no initializer is specified for an object, the object is default-initialized.

13

#

If the entity being initialized does not have class or array type, theexpression-list in a parenthesized initializer shall be a single expression.

14

#

The initialization that occurs in the = form of abrace-or-equal-initializer orcondition ([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 adesignated-initializer-clause ([dcl.init.aggr]), is calledcopy-initialization.

[Note 5:

Copy-initialization can invoke a move ([class.copy.ctor]).

— end note]

15

#

The initialization that occurs

for an initializer that is a parenthesized expression-list or a braced-init-list,

for a new-initializer ([expr.new]),

in a static_cast expression ([expr.static.cast]),

in a functional notation type conversion ([expr.type.conv]), and

in the braced-init-list form of a condition

is calleddirect-initialization.

16

#

The semantics of initializers are as follows.

Thedestination type is the cv-unqualified type of the object or reference being initialized and thesource type is the type of the initializer expression.

If the initializer is not a single (possibly parenthesized) expression, the source type is not defined.

  • (16.1)

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

  • (16.2)

    If the destination type is a reference type, see [dcl.init.ref].

  • (16.3)

    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 ofwchar_t, and the initializer is a string-literal, see [dcl.init.string].

  • (16.4)

    If the initializer is (), the object is value-initialized. [Note 6: Since() is not permitted by the syntax forinitializer,X a(); is not the declaration of an object of classX, but the declaration of a function taking no arguments and returning anX. The form() can appear in certain other initialization contexts ([expr.new], [expr.type.conv], [class.base.init]). — end note]

  • (16.5)

    Otherwise, if the destination type is an array, the object is initialized as follows. The initializer shall be of the form( expression-list ). Let x1, …, xk 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 ith array element is copy-initialized withxi for each 1 ≤ i ≤ k, and value-initialized for each k<i≤n. For each 1≤i<j≤n, every value computation and side effect associated with the initialization of the ith element of the array is sequenced before those associated with the initialization of the jth element.

  • (16.6)

    Otherwise, if the destination type is a class type:

    • (16.6.1)

      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]

    • (16.6.2)

      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: + (16.6.2.1) 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).

      • [(16.6.2.2)](#16.6.2.2)
        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 e1, …, en be the elements of the aggregate ([dcl.init.aggr]). Let x1, …, xk be the elements of the expression-list. If k is greater than n, the program is ill-formed. The element ei is copy-initialized withxi for 1 ≤ i ≤ k. The remaining elements are initialized with their default member initializers, if any, and otherwise are value-initialized. For each 1≤i<j≤n, every value computation and side effect associated with the initialization of ei is sequenced before those associated with the initialization of ej. [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]

+
      [(16.6.2.3)](#16.6.2.3)
      Otherwise, the initialization is ill-formed[.](#16.6.2.3.sentence-1)
  • (16.6.3)

    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.

  • (16.7)

    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.

  • (16.8)

    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.

  • (16.9)

    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 isimplementation-defined. [Note 8: An expression of type “cv1€ can initialize an object of type “cv2€ independently of the cv-qualifierscv1 and cv2. int a;const int b = a;int c = b; — end note]

17

#

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.

18

#

An initializer-clause followed by an ellipsis is a pack expansion ([temp.variadic]).

19

#

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

20

#

If the initializer is a parenthesized expression-list, the expressions are evaluated in the order specified for function calls ([expr.call]).

21

#

The same identifier shall not appear in multiple designators of adesignated-initializer-list.

22

#

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.

23

#

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 is0 to a pointer type results in a null pointer value.