Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/language/zero initialization"

From cppreference.com
< cpp‎ | language
m (Added missing C++11 inline marks for thread-local variables.)
(Added CWG issue #277 DR.)
Line 8: Line 8:
  
 
{{sdsc begin}}
 
{{sdsc begin}}
{{sdsc | num=1 | {{ttb|static}} {{spar|T}} {{spar| object}} {{ttb|;}}}}
+
{{sdsc|num=1|{{ttb|static}} {{spar|T}} {{spar| object}} {{ttb|;}}}}
{{sdsc | num=2 |notes=<br><br>{{mark since c++11}}|{{spar|T}} {{ttb|()}} {{ttb|;}}
+
{{sdsc|num=2|notes=<br><br>{{mark since c++11}}|{{spar|T}} {{ttb|()}} {{ttb|;}}
 
{{spar|T}} {{spar|t}} {{ttb|{{=}}}} {{ttb|{}<nowiki/>}} {{ttb|;}} <br>
 
{{spar|T}} {{spar|t}} {{ttb|{{=}}}} {{ttb|{}<nowiki/>}} {{ttb|;}} <br>
 
{{spar|T}} {{ttb|{}<nowiki/>}} {{ttb|;}}
 
{{spar|T}} {{ttb|{}<nowiki/>}} {{ttb|;}}
 
}}
 
}}
{{sdsc | num=3 | {{spar|CharT}} {{spar|array}} {{ttb|[}} {{spar|n}} {{ttb|]}} {{ttb|{{=}}}} {{ttb|"";}}}}
+
{{sdsc|num=3|{{spar|CharT}} {{spar|array}} {{ttb|[}} {{spar|n}} {{ttb|]}} {{ttb|{{=}}}} {{ttb|"";}}}}
 
{{sdsc end}}
 
{{sdsc end}}
  
Line 21: Line 21:
 
@1@ For every named variable with static{{rev inl|since=c++11| or thread-local}} {{rlp|storage duration}} that is not subject to {{rlp|constant initialization}}, before any other initialization.
 
@1@ For every named variable with static{{rev inl|since=c++11| or thread-local}} {{rlp|storage duration}} that is not subject to {{rlp|constant initialization}}, before any other initialization.
 
@2@ As part of {{rlp|value initialization|value-initialization}} sequence for non-class types and for members of value-initialized class types that have no constructors, including value initialization of elements of {{rlp|aggregate initialization|aggregates}} for which no initializers are provided.
 
@2@ As part of {{rlp|value initialization|value-initialization}} sequence for non-class types and for members of value-initialized class types that have no constructors, including value initialization of elements of {{rlp|aggregate initialization|aggregates}} for which no initializers are provided.
@3@ When an array of any {{rlp|types#Character_types|character type}} is {{rlp|aggregate initialization#Character arrays|initialized with a string literal}} that is too short, the remainder of the array is zero-initialized.
+
@3@ When an array of any {{rlp|types#Character types|character type}} is {{rlp|aggregate initialization#Character arrays|initialized with a string literal}} that is too short, the remainder of the array is zero-initialized.
  
 
The effects of zero initialization are:
 
The effects of zero initialization are:
Line 36: Line 36:
  
 
===Notes===
 
===Notes===
As described in {{rlp|initialization#Non-local_variables|non-local initialization}}, static{{rev inl|since=c++11| and thread-local}} variables that aren't constant-initialized are zero-initialized before any other initialization takes place. If the definition of a non-class non-local variable has no initializer, then default initialization does nothing, leaving the result of the earlier zero-initialization unmodified.
+
As described in {{rlp|initialization#Non-local variables|non-local initialization}}, static{{rev inl|since=c++11| and thread-local}} variables that aren't constant-initialized are zero-initialized before any other initialization takes place. If the definition of a non-class non-local variable has no initializer, then default initialization does nothing, leaving the result of the earlier zero-initialization unmodified.
  
 
A zero-initialized pointer is the null pointer value of its type, even if the value of the null pointer is not integral zero.
 
A zero-initialized pointer is the null pointer value of its type, even if the value of the null pointer is not integral zero.
Line 48: Line 48:
 
#include <iostream>
 
#include <iostream>
  
struct A {
+
struct A
     int a,b,c;
+
{
 +
     int a, b, c;
 
};
 
};
  
double f[3]; // zero-initialized to three 0.0's
+
double f[3];   // zero-initialized to three 0.0's
int* p; // zero-initialized to null pointer value (even if the value is not integral 0)
+
 
std::string s; // zero-initialized to indeterminate value
+
int* p;       // zero-initialized to null pointer value
               // then default-initialized to "" by the std::string default constructor
+
              // (even if the value is not integral 0)
 +
 
 +
std::string s; // zero-initialized to indeterminate value, then
 +
               // default-initialized to "" by the std::string default constructor
 +
 
 
int main(int argc, char*[])
 
int main(int argc, char*[])
 
{
 
{
 
     delete p; // safe to delete a null pointer
 
     delete p; // safe to delete a null pointer
 +
   
 
     static int n = argc; // zero-initialized to 0 then copy-initialized to argc
 
     static int n = argc; // zero-initialized to 0 then copy-initialized to argc
 
     std::cout << "n = " << n << '\n';
 
     std::cout << "n = " << n << '\n';
 +
   
 
     A a = A(); // the effect is same as: A a{}; or A a = {};
 
     A a = A(); // the effect is same as: A a{}; or A a = {};
 
     std::cout << "a = {" << a.a << ' ' << a.b << ' ' << a.c << "}\n";
 
     std::cout << "a = {" << a.a << ' ' << a.b << ' ' << a.c << "}\n";
 
}
 
}
| p=true <!-- argc -->
+
|p=true <!-- argc -->
| output=
+
|output=
 
n = 1
 
n = 1
 
a = {0 0 0}
 
a = {0 0 0}
Line 72: Line 79:
 
===Defect reports===
 
===Defect reports===
 
{{dr list begin}}
 
{{dr list begin}}
{{dr list item|wg=cwg|dr=2026|std=C++98|before=zero-init was specified to always occur first, even before constant-init|after=no zero-init if constant init applies}}
+
{{dr list item|wg=cwg|dr=277|std=C++98|before=pointers might be initialized with a non-constant<br>expression of value 0, which is not a null pointer constant|after=must initialize with an integral<br>constant expression of value 0}}
 +
{{dr list item|wg=cwg|dr=2026|std=C++98|before=zero initialization was specified to always<br>occur first, even before constant initialization|after=no zero initialization if<br>constant initialization applies}}
 
{{dr list end}}
 
{{dr list end}}
  
 
===See also===
 
===See also===
* {{rlp | constructor}}
+
* {{rlp|constructor}}
* {{rlp | copy assignment}}
+
* {{rlp|copy assignment}}
* {{rlp | default constructor}}
+
* {{rlp|default constructor}}
* {{rlp | initialization}}
+
* {{rlp|initialization}}
** {{rlp | aggregate initialization}}
+
** {{rlp|aggregate initialization}}
** {{rlp | constant initialization}}
+
** {{rlp|constant initialization}}
** {{rlp | copy initialization}}
+
** {{rlp|copy initialization}}
** {{rlp | default initialization}}
+
** {{rlp|default initialization}}
** {{rlp | direct initialization}}
+
** {{rlp|direct initialization}}
** {{rlp | list initialization}}
+
** {{rlp|list initialization}}
** {{rlp | value initialization}}
+
** {{rlp|value initialization}}
* {{rlp | move assignment}}
+
* {{rlp|move assignment}}
* {{rlp | new}}
+
* {{rlp|new}}
  
 
{{langlinks|de|es|fr|it|ja|pt|ru|zh}}
 
{{langlinks|de|es|fr|it|ja|pt|ru|zh}}

Revision as of 23:35, 24 January 2022

 
 
C++ language
General topics
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++17*)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
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
explicit (C++11)
static

Special member functions
Templates
Miscellaneous
 
 

Sets the initial value of an object to zero.

Contents

Syntax

Note that this is not the syntax for zero initialization, which does not have a dedicated syntax in the language. These are examples of other types of initializations, which might perform zero initialization.

static T object ; (1)
T () ;

T t = {} ;
T {} ;

(2)

(since C++11)
CharT array [ n ] = ""; (3)

Explanation

Zero initialization is performed in the following situations:

1) For every named variable with static or thread-local(since C++11) storage duration that is not subject to constant initialization, before any other initialization.
2) As part of value-initialization sequence for non-class types and for members of value-initialized class types that have no constructors, including value initialization of elements of aggregates for which no initializers are provided.
3) When an array of any character type is initialized with a string literal that is too short, the remainder of the array is zero-initialized.

The effects of zero initialization are:

  • If T is a scalar type, the object's initial value is the integral constant zero explicitly converted to T.
  • If T is an non-union class type, all base classes and non-static data members are zero-initialized, and all padding is initialized to zero bits. The constructors, if any, are ignored.
  • If T is a union type, the first non-static named data member is zero-initialized and all padding is initialized to zero bits.
  • If T is array type, each element is zero-initialized.
  • If T is reference type, nothing is done.

Notes

As described in non-local initialization, static and thread-local(since C++11) variables that aren't constant-initialized are zero-initialized before any other initialization takes place. If the definition of a non-class non-local variable has no initializer, then default initialization does nothing, leaving the result of the earlier zero-initialization unmodified.

A zero-initialized pointer is the null pointer value of its type, even if the value of the null pointer is not integral zero.

Example

#include <string>
#include <iostream>
 
struct A
{
    int a, b, c;
};
 
double f[3];   // zero-initialized to three 0.0's
 
int* p;        // zero-initialized to null pointer value
               // (even if the value is not integral 0)
 
std::string s; // zero-initialized to indeterminate value, then
               // default-initialized to "" by the std::string default constructor
 
int main(int argc, char*[])
{
    delete p; // safe to delete a null pointer
 
    static int n = argc; // zero-initialized to 0 then copy-initialized to argc
    std::cout << "n = " << n << '\n';
 
    A a = A(); // the effect is same as: A a{}; or A a = {};
    std::cout << "a = {" << a.a << ' ' << a.b << ' ' << a.c << "}\n";
}

Possible output:

n = 1
a = {0 0 0}

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
CWG 277 C++98 pointers might be initialized with a non-constant
expression of value 0, which is not a null pointer constant
must initialize with an integral
constant expression of value 0
CWG 2026 C++98 zero initialization was specified to always
occur first, even before constant initialization
no zero initialization if
constant initialization applies

See also