[dcl.init.general] # 9 Declarations [[dcl]](./#dcl) ## 9.5 Initializers [[dcl.init]](dcl.init#general) ### 9.5.1 General [dcl.init.general] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4912) The process of initialization described in [[dcl.init]](dcl.init "9.5 Initializers") applies to all initializations regardless of syntactic context, including the initialization of a function parameter ([[expr.call]](expr.call "7.6.1.3 Function call")), the initialization of a return value ([[stmt.return]](stmt.return "8.8.4 The return statement")), or when an initializer follows a declarator[.](#1.sentence-1) [initializer:](#nt:initializer "9.5.1 General [dcl.init.general]") [*brace-or-equal-initializer*](#nt:brace-or-equal-initializer "9.5.1 General [dcl.init.general]") ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]") ) [brace-or-equal-initializer:](#nt:brace-or-equal-initializer "9.5.1 General [dcl.init.general]") = [*initializer-clause*](#nt:initializer-clause "9.5.1 General [dcl.init.general]") [*braced-init-list*](#nt:braced-init-list "9.5.1 General [dcl.init.general]") [initializer-clause:](#nt:initializer-clause "9.5.1 General [dcl.init.general]") [*assignment-expression*](expr.assign#nt:assignment-expression "7.6.19 Assignment and compound assignment operators [expr.assign]") [*braced-init-list*](#nt:braced-init-list "9.5.1 General [dcl.init.general]") [braced-init-list:](#nt:braced-init-list "9.5.1 General [dcl.init.general]") { [*initializer-list*](#nt:initializer-list "9.5.1 General [dcl.init.general]") ,opt } { [*designated-initializer-list*](#nt:designated-initializer-list "9.5.1 General [dcl.init.general]") ,opt } { } [initializer-list:](#nt:initializer-list "9.5.1 General [dcl.init.general]") [*initializer-clause*](#nt:initializer-clause "9.5.1 General [dcl.init.general]") ...opt [*initializer-list*](#nt:initializer-list "9.5.1 General [dcl.init.general]") , [*initializer-clause*](#nt:initializer-clause "9.5.1 General [dcl.init.general]") ...opt [designated-initializer-list:](#nt:designated-initializer-list "9.5.1 General [dcl.init.general]") [*designated-initializer-clause*](#nt:designated-initializer-clause "9.5.1 General [dcl.init.general]") [*designated-initializer-list*](#nt:designated-initializer-list "9.5.1 General [dcl.init.general]") , [*designated-initializer-clause*](#nt:designated-initializer-clause "9.5.1 General [dcl.init.general]") [designated-initializer-clause:](#nt:designated-initializer-clause "9.5.1 General [dcl.init.general]") [*designator*](#nt:designator "9.5.1 General [dcl.init.general]") [*brace-or-equal-initializer*](#nt:brace-or-equal-initializer "9.5.1 General [dcl.init.general]") [designator:](#nt:designator "9.5.1 General [dcl.init.general]") . [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") [expr-or-braced-init-list:](#nt:expr-or-braced-init-list "9.5.1 General [dcl.init.general]") [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") [*braced-init-list*](#nt:braced-init-list "9.5.1 General [dcl.init.general]") [*Note [1](#note-1)*: The rules in [[dcl.init]](dcl.init "9.5 Initializers") apply even if the grammar permits only the [*brace-or-equal-initializer*](#nt:brace-or-equal-initializer "9.5.1 General [dcl.init.general]") form of [*initializer*](#nt:initializer "9.5.1 General [dcl.init.general]") in a given context[.](#1.sentence-2) — *end note*] [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4978) Except for objects declared with the constexpr specifier, for which see [[dcl.constexpr]](dcl.constexpr "9.2.6 The constexpr and consteval specifiers"), an [*initializer*](#nt:initializer "9.5.1 General [dcl.init.general]") 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[.](#2.sentence-1) [*Example [1](#example-1)*: int f(int);int a = 2;int b = f(a);int c(b); — *end example*] [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4993) [*Note [2](#note-2)*: Default arguments are more restricted; see [[dcl.fct.default]](dcl.fct.default "9.3.4.7 Default arguments")[.](#3.sentence-1) — *end note*] [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4998) [*Note [3](#note-3)*: The order of initialization of variables with static storage duration is described in [[basic.start]](basic.start "6.10.3 Start and termination") and [[stmt.dcl]](stmt.dcl "8.10 Declaration statement")[.](#4.sentence-1) — *end note*] [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5004) A declaration D of a variable with linkage shall not have an [*initializer*](#nt:initializer "9.5.1 General [dcl.init.general]") if D inhabits a block scope[.](#5.sentence-1) [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5009) To [*zero-initialize*](#def:zero-initialization "9.5.1 General [dcl.init.general]") an object or reference of type T means: - [(6.1)](#6.1) if T is std​::​meta​::​info, the object is initialized to a null reflection value; - [(6.2)](#6.2) if T is any other scalar type ([[basic.types.general]](basic.types.general#term.scalar.type "6.9.1 General")), the object is initialized to the value obtained by converting the integer literal 0 (zero) to T;[78](#footnote-78 "As specified in [conv.ptr], converting an integer literal whose value is 0 to a pointer type results in a null pointer value.") - [(6.3)](#6.3) ifT is a (possibly cv-qualified) non-union class type, its padding bits ([[basic.types.general]](basic.types.general#term.padding.bits "6.9.1 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; - [(6.4)](#6.4) ifT is a (possibly cv-qualified) union type, its padding bits ([[basic.types.general]](basic.types.general#term.padding.bits "6.9.1 General")) are initialized to zero bits and the object's first non-static named data member is zero-initialized; - [(6.5)](#6.5) ifT is an array type, each element is zero-initialized; - [(6.6)](#6.6) ifT is a reference type, no initialization is performed[.](#6.sentence-1) [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5062) To[*default-initialize*](#def:default-initialization "9.5.1 General [dcl.init.general]") an object of typeT means: - [(7.1)](#7.1) IfT is a (possibly cv-qualified) class type ([[class]](class "11 Classes")), constructors are considered[.](#7.1.sentence-1) The applicable constructors are enumerated ([[over.match.ctor]](over.match.ctor "12.2.2.4 Initialization by constructor")), and the best one for the[*initializer*](#nt:initializer "9.5.1 General [dcl.init.general]") () is chosen through overload resolution ([[over.match]](over.match "12.2 Overload resolution"))[.](#7.1.sentence-2) The constructor thus selected is called, with an empty argument list, to initialize the object[.](#7.1.sentence-3) - [(7.2)](#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.2.sentence-1) - [(7.3)](#7.3) If T is std​::​meta​::​info, the object is zero-initialized[.](#7.3.sentence-1) - [(7.4)](#7.4) Otherwise, no initialization is performed[.](#7.4.sentence-1) [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5095) A class type T is [*const-default-constructible*](#def:const-default-constructible "9.5.1 General [dcl.init.general]") if default-initialization of T would invoke a user-provided constructor of T (not inherited from a base class) or if - [(8.1)](#8.1) 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, - [(8.2)](#8.2) if T is a union with at least one non-static data member, exactly one variant member has a default member initializer, - [(8.3)](#8.3) 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 - [(8.4)](#8.4) each potentially constructed base class of T is const-default-constructible[.](#8.sentence-1) 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[.](#8.sentence-2) [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5123) To[*value-initialize*](#def:value-initialization "9.5.1 General [dcl.init.general]") an object of typeT means: - [(9.1)](#9.1) IfT is a (possibly cv-qualified) class type ([[class]](class "11 Classes")), then let C be the constructor selected to default-initialize the object, if any[.](#9.1.sentence-1) If C is not user-provided, the object is first zero-initialized[.](#9.1.sentence-2) In all cases, the object is then default-initialized[.](#9.1.sentence-3) - [(9.2)](#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.2.sentence-1) - [(9.3)](#9.3) Otherwise, the object is zero-initialized[.](#9.3.sentence-1) [10](#10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5152) A program that calls for default-initialization or value-initialization of an entity of reference type is ill-formed[.](#10.sentence-1) [11](#11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5158) [*Note [4](#note-4)*: For every object with static storage duration, static initialization ([[basic.start.static]](basic.start.static "6.10.3.2 Static initialization")) is performed at program startup before any other initialization takes place[.](#11.sentence-1) In some cases, additional initialization is done later[.](#11.sentence-2) — *end note*] [12](#12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5166) If no initializer is specified for an object, the object is default-initialized[.](#12.sentence-1) [13](#13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5169) If the entity being initialized does not have class or array type, the[*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]") in a parenthesized initializer shall be a single expression[.](#13.sentence-1) [14](#14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5174) The initialization that occurs in the = form of a[*brace-or-equal-initializer*](#nt:brace-or-equal-initializer "9.5.1 General [dcl.init.general]") or[*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]") ([[stmt.select]](stmt.select "8.5 Selection statements")), as well as in argument passing, function return, throwing an exception ([[except.throw]](except.throw "14.2 Throwing an exception")), handling an exception ([[except.handle]](except.handle "14.4 Handling an exception")), and aggregate member initialization other than by a[*designated-initializer-clause*](#nt:designated-initializer-clause "9.5.1 General [dcl.init.general]") ([[dcl.init.aggr]](dcl.init.aggr "9.5.2 Aggregates")), is called[*copy-initialization*](#def:copy-initialization "9.5.1 General [dcl.init.general]")[.](#14.sentence-1) [*Note [5](#note-5)*: Copy-initialization can invoke a move ([[class.copy.ctor]](class.copy.ctor "11.4.5.3 Copy/move constructors"))[.](#14.sentence-2) — *end note*] [15](#15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5191) The initialization that occurs - [(15.1)](#15.1) for an [*initializer*](#nt:initializer "9.5.1 General [dcl.init.general]") that is a parenthesized [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]") or a [*braced-init-list*](#nt:braced-init-list "9.5.1 General [dcl.init.general]"), - [(15.2)](#15.2) for a [*new-initializer*](expr.new#nt:new-initializer "7.6.2.8 New [expr.new]") ([[expr.new]](expr.new "7.6.2.8 New")), - [(15.3)](#15.3) in a static_cast expression ([[expr.static.cast]](expr.static.cast "7.6.1.9 Static cast")), - [(15.4)](#15.4) in a functional notation type conversion ([[expr.type.conv]](expr.type.conv "7.6.1.4 Explicit type conversion (functional notation)")), and - [(15.5)](#15.5) in the [*braced-init-list*](#nt:braced-init-list "9.5.1 General [dcl.init.general]") form of a [*condition*](stmt.pre#nt:condition "8.1 Preamble [stmt.pre]") is called[*direct-initialization*](#def:direct-initialization "9.5.1 General [dcl.init.general]")[.](#15.sentence-1) [16](#16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L5204) The semantics of initializers are as follows[.](#16.sentence-1) The[*destination type*](#def:destination_type) is the cv-unqualified type of the object or reference being initialized and the[*source type*](#def:source_type) is the type of the initializer expression[.](#16.sentence-2) If the initializer is not a single (possibly parenthesized) expression, the source type is not defined[.](#16.sentence-3) - [(16.1)](#16.1) If the initializer is a (non-parenthesized) [*braced-init-list*](#nt:braced-init-list "9.5.1 General [dcl.init.general]") or is = [*braced-init-list*](#nt:braced-init-list "9.5.1 General [dcl.init.general]"), the object or reference is list-initialized ([[dcl.init.list]](dcl.init.list "9.5.5 List-initialization"))[.](#16.1.sentence-1) - [(16.2)](#16.2) If the destination type is a reference type, see [[dcl.init.ref]](dcl.init.ref "9.5.4 References")[.](#16.2.sentence-1) - [(16.3)](#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*](lex.string#nt:string-literal "5.13.5 String literals [lex.string]"), see [[dcl.init.string]](dcl.init.string "9.5.3 Character arrays")[.](#16.3.sentence-1) - [(16.4)](#16.4) If the initializer is (), the object is value-initialized[.](#16.4.sentence-1) [*Note [6](#note-6)*: Since() is not permitted by the syntax for[*initializer*](#nt:initializer "9.5.1 General [dcl.init.general]"),X a(); is not the declaration of an object of classX, but the declaration of a function taking no arguments and returning anX[.](#16.4.sentence-2) The form() can appear in certain other initialization contexts ([[expr.new]](expr.new "7.6.2.8 New"), [[expr.type.conv]](expr.type.conv "7.6.1.4 Explicit type conversion (functional notation)"), [[class.base.init]](class.base.init "11.9.3 Initializing bases and members"))[.](#16.4.sentence-3) — *end note*] - [(16.5)](#16.5) Otherwise, if the destination type is an array, the object is initialized as follows[.](#16.5.sentence-1) The [*initializer*](#nt:initializer "9.5.1 General [dcl.init.general]") shall be of the form( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]") )[.](#16.5.sentence-2) Let x1, …, xk be the elements of the [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]")[.](#16.5.sentence-3) If the destination type is an array of unknown bound, it is defined as having k elements[.](#16.5.sentence-4) Let n denote the array size after this potential adjustment[.](#16.5.sentence-5) If k is greater than n, the program is ill-formed[.](#16.5.sentence-6) Otherwise, the ith array element is copy-initialized withxi for each 1 ≤ i ≤ k, and value-initialized for each k