General topics | ||||||||||||||||
Flow control | ||||||||||||||||
Conditional execution statements | ||||||||||||||||
Iteration statements (loops) | ||||||||||||||||
Jump statements | ||||||||||||||||
Functions | ||||||||||||||||
Function declaration | ||||||||||||||||
Lambda function expression | ||||||||||||||||
inline specifier | ||||||||||||||||
Dynamic exception specifications(until C++17*) | ||||||||||||||||
noexcept specifier(C++11) | ||||||||||||||||
Exceptions | ||||||||||||||||
Namespaces | ||||||||||||||||
Types | ||||||||||||||||
Specifiers | ||||||||||||||||
| ||||||||||||||||
Storage duration specifiers | ||||||||||||||||
Initialization | ||||||||||||||||
Expressions | ||||||||||||||||
Alternative representations | ||||||||||||||||
Literals | ||||||||||||||||
Boolean -Integer -Floating-point | ||||||||||||||||
Character -String -nullptr(C++11) | ||||||||||||||||
User-defined(C++11) | ||||||||||||||||
Utilities | ||||||||||||||||
Attributes(C++11) | ||||||||||||||||
Types | ||||||||||||||||
typedef declaration | ||||||||||||||||
Type alias declaration(C++11) | ||||||||||||||||
Casts | ||||||||||||||||
Memory allocation | ||||||||||||||||
Classes | ||||||||||||||||
Class-specific function properties | ||||||||||||||||
| ||||||||||||||||
Special member functions | ||||||||||||||||
Templates | ||||||||||||||||
Miscellaneous | ||||||||||||||||
Initialization of a variable provides its initial value at the time of construction.
The initial value may be provided in the initializer section of adeclarator or anew expression. It also takes place during function calls: function parameters and the function return values are also initialized.
Contents |
For each declarator, theinitializer (if exists) may be one of the following:
= expression | (1) | ||||||||
= {} = { initializer-list} = { designated-initializer-list} | (2) | (since C++20) | |||||||
( expression-list) ( initializer-list) | (3) | (until C++11) (since C++11) | |||||||
{} { initializer-list} { designated-initializer-list} | (4) | (since C++11) (since C++11) (since C++20) | |||||||
expression | - | any expression (except unparenthesizedcomma expressions) |
expression-list | - | a comma-separated list of expressions (except unparenthesized comma expressions) |
initializer-list | - | a comma-separated list of initializer clauses (see below) |
designated-initializer-list | - | a comma-separated list ofdesignated initializer clauses |
Aninitializer clause may be one of the following:
expression | (1) | ||||||||
{} | (2) | ||||||||
{ initializer-list} | (3) | ||||||||
{ designated-initializer-list} | (4) | (since C++20) | |||||||
Syntaxes(2-4) are collectively calledbrace-enclosed initializer list.
If no initializer is specified for an object, the object isdefault-initialized. If no initializer is specified for areference, the program is ill-formed.
If the initializer specified for an object is() (cannot appear in declarators due to the syntax restriction), the object isvalue-initialized. If the initializer specified for a reference is(), the program is ill-formed.
The semantics of initializers are as follows:
T
:
| (until C++11) |
| (since C++11) |
#include <string> std::string s1;// default-initializationstd::string s2();// NOT an initialization!// actually declares a function “s2”// with no parameter and returns std::stringstd::string s3="hello";// copy-initializationstd::string s4("hello");// direct-initializationstd::string s5{'a'};// list-initialization (since C++11) char a[3]={'a','b'};// aggregate initialization// (part of list initialization since C++11)char& c= a[0];// reference initialization
All non-local variables with staticstorage duration are initialized as part of program startup, before the execution of themain function begins (unless deferred, see below). All non-local variables with thread-local storage duration are initialized as part of thread launch, sequenced-before the execution of the thread function begins. For both of these classes of variables, initialization occurs in two distinct stages:
There are two forms of static initialization:
In practice:
.bss
segment of the program image, which occupies no space on disk and is zeroed out by the OS when loading the program.After all static initialization is completed, dynamic initialization of non-local variables occurs in the following situations:
2)Partially-ordered dynamic initialization, which applies to all inline variables that are not an implicitly or explicitly instantiated specialization. If a partially-ordered V is defined before ordered or partially-ordered W in every translation unit, the initialization of V is sequenced before the initialization of W (or happens-before, if the program starts a thread). | (since C++17) |
If the initialization of a non-local variable with static or thread storage duration exits via an exception,std::terminate is called.
The compilers are allowed to initialize dynamically-initialized variables as part of static initialization (essentially, at compile time), if the following conditions are both true:
Because of the rule above, if initialization of some objecto1
refers to a namespace-scope objecto2
, which potentially requires dynamic initialization, but is defined later in the same translation unit, it is unspecified whether the value ofo2
used will be the value of the fully initializedo2
(because the compiler promoted initialization ofo2
to compile time) or will be the value ofo2
merely zero-initialized.
inlinedouble fd(){return1.0;} externdouble d1; double d2= d1;// unspecified:// dynamically initialized to 0.0 if d1 is dynamically initialized, or// dynamically initialized to 1.0 if d1 is statically initialized, or// statically initialized to 0.0 (because that would be its value// if both variables were dynamically initialized) double d1= fd();// may be initialized statically or dynamically to 1.0
It is implementation-defined whether dynamic initialization happens-before the first statement of the main function (for statics) or the initial function of the thread (for thread-locals), or deferred to happen after.
If the initializationof a non-inline variable(since C++17) is deferred to happen after the first statement of main/thread function, it happens before the firstODR-use of any variable with static/thread storage duration defined in the same translation unit as the variable to be initialized. If no variable or function is ODR-used from a given translation unit, the non-local variables defined in that translation unit may never be initialized (this models the behavior of an on-demand dynamic library). However, as long as anything from a translation unit is ODR-used, all non-local variables whose initialization or destruction has side effects will be initialized even if they are not used in the program.
If the initialization of an inline variable is deferred, it happens before the firstODR-use of that specific variable. | (since C++17) |
// ============// == File 1 == #include "a.h"#include "b.h" B b;A::A(){ b.Use();} // ============// == File 2 == #include "a.h" A a; // ============// == File 3 == #include "a.h"#include "b.h" extern A a;extern B b; int main(){ a.Use(); b.Use();} // If a is initialized before main is entered, b may still be uninitialized// at the point where A::A() uses it (because dynamic initialization is// indeterminately sequenced across translation units) // If a is initialized at some point after the first statement of main (which odr-uses// a function defined in File 1, forcing its dynamic initialization to run),// then b will be initialized prior to its use in A::A
For initialization of local (that is, block scope) static and thread-local variables, seestatic block variables.
Initializer is not allowed in a block-scope declaration of a variable withexternal or internal linkage. Such a declaration must appear withextern and cannot be a definition.
Non-static data members can be initialized withmember initializer list or with adefault member initializer.
The order of destruction of non-local variables is described instd::exit.
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 270 | C++98 | the order of initializing static data members of class templates was unspecified | specified as unordered except for explicit specializations and definitions |
CWG 441 | C++98 | non-local references with static storage duration were not always initialized before dynamic initializations | considered as static initialization, always initialized before dynamic initializations |
CWG 1415 | C++98 | a block-scopeextern variable declaration could be a definition | prohibited (no initializer allowed in such declarations) |
CWG 2599 | C++98 | it was unclear whether evaluating function arguments in the initializer is part of initialization | it is part of initialization |
C documentation forInitialization |