Namespaces
Variants

Zero-initialization

From cppreference.net
C++ language
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
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
Special member functions
Templates
Miscellaneous

オブジェクトの初期値をゼロに設定します。

目次

構文

これはゼロ初期化の構文ではないことに注意してください。ゼロ初期化には言語において専用の構文が存在しません。これらは他の種類の初期化の例であり、ゼロ初期化を実行する可能性があります。

static T object ; (1)
T () ;

T t = {} ;

T {} ; (C++11以降)

(2)
CharT array [ n ] = " short-sequence "; (3)

説明

ゼロ初期化は以下の状況で実行されます:

1) 静的 またはスレッドローカル (C++11以降) ストレージ期間 を持つすべての名前付き変数で、 定数初期化 の対象とならないものに対して、他のいずれの初期化よりも前に実行されます。
2) 非クラス型およびコンストラクタを持たない値初期化されたクラス型のメンバーに対する value-initialization シーケンスの一部として、また初期化子が提供されていない aggregates の要素の値初期化を含む。
3) 任意の character type の配列が initialized with a string literal で初期化され、その文字列リテラルが短すぎる場合、配列の残りの部分はゼロ初期化されます。

ゼロ初期化の効果は以下の通りです:

  • T スカラ型 の場合、オブジェクトは整数リテラル 0 T 明示的に変換 して得られる値で初期化されます。
  • T が非共用体クラス型の場合:
  • T が共用体型の場合:
  • すべてのパディングビットはゼロビットに初期化され、
  • オブジェクトの最初の非静的名前付きデータメンバはゼロ初期化されます。
  • T が配列型の場合、各要素はゼロ初期化されます。
  • T が参照型の場合、何も行われません。

注記

非ローカル初期化 で説明されているように、定数初期化されない静的 およびスレッドローカル (C++11以降) 変数は、他の初期化が行われる前にゼロ初期化されます。非クラス型の非ローカル変数の定義に初期化子がない場合、デフォルト初期化は何も行わず、以前のゼロ初期化の結果が変更されずに残ります。

ゼロ初期化されたポインタは、その型のヌルポインタ値であり、たとえヌルポインタの値が整数のゼロでない場合でも同様です。

#include <iostream>
#include <string>
struct A
{
    int a, b, c;
};
double f[3];   // 3つの0.0にゼロ初期化
int* p;        // ヌルポインタ値にゼロ初期化
               //(値が整数の0でない場合でも)
std::string s; // 不定値にゼロ初期化され、その後
               // std::stringデフォルトコンストラクタにより""にデフォルト初期化
int main(int argc, char*[])
{
    delete p; // ヌルポインタのdeleteは安全
    static int n = argc; // 0にゼロ初期化され、その後argcにコピー初期化
    std::cout << "n = " << n << '\n';
    A a = A(); // 効果は A a{}; または A a = {}; と同じ
    std::cout << "a = {" << a.a << ' ' << a.b << ' ' << a.c << "}\n";
}

出力例:

n = 1
a = {0 0 0}

不具合報告

以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 正しい動作
CWG 277 C++98 ポインタが値0の非定数式で初期化される可能性があったが、
これはnullポインタ定数ではない
値0の整数定数式で
初期化しなければならない
CWG 694 C++98 クラス型のゼロ初期化ではパディングが無視されていた パディングはゼロビットで初期化される
CWG 903 C++98 スカラ型のゼロ初期化では初期値が値0の
整数定数式から変換された値に設定されていた
オブジェクトは整数リテラル 0 から変換された値で初期化される
CWG 2026 C++98 ゼロ初期化は常に最初に発生すると規定されていたが、
定数初期化よりも前でも発生していた
定数初期化が適用される場合は
ゼロ初期化は行われない
CWG 2196 C++98 クラス型のゼロ初期化では基底クラスの部分オブジェクトが無視されていた これらもゼロ初期化される
CWG 2253 C++98 ゼロ初期化が無名ビットフィールドに適用されるか不明確だった 適用される(すべてのパディングビットは
ゼロビットで初期化される)

関連項目