名前空間
変種
操作

ゼロ初期化

From cppreference.com
< cpp‎ | language
 
 
C++言語
全般
フロー制御
条件実行文
if
繰り返し文 (ループ)
for
範囲for (C++11)
ジャンプ文
関数
関数宣言
ラムダ式
inline指定子
動的例外仕様 (C++17まで*)
noexcept指定子 (C++11)
例外
名前空間
指定子
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点数
文字 - 文字列 - nullptr (C++11)
ユーザー定義 (C++11)
ユーティリティ
属性 (C++11)
typedef宣言
型エイリアス宣言 (C++11)
キャスト
メモリ確保
クラス
クラス固有の関数プロパティ
explicit (C++11)
static

特殊メンバ関数
テンプレート
その他
 
 

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

目次

[編集] 構文

これはゼロ初期化の構文ではありません。ゼロ初期化は言語に専用の構文を持っていません。これらはゼロ初期化を実行する可能性のある、他の型の初期化の例です。

static T object ; (1)
T () ;

T t = {} ;

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

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

[編集] 解説

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

1) 定数初期化の対象とならない、static またはスレッドローカル(C++11以降)記憶域期間を持つすべての名前付き変数に対し、他のどの初期化よりも前に。
2) 非クラス型、およびコンストラクタを持たない値初期化されたクラス型のメンバに対する値初期化シーケンスの一部として、初期化子が提供されない集成体の要素の値初期化を含む。
3) 任意の文字型の配列が、短すぎる文字列リテラルで初期化された場合、配列の残りの部分がゼロ初期化されます。

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

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

[編集] 備考

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

ゼロ初期化されたポインタは、その型のヌルポインタ値です。ヌルポインタの値が整数ゼロでなくても同様です。

[編集]

#include <iostream>
#include <string>
 
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";
}

実行結果の例

n = 1
a = {0 0 0}

[編集] 欠陥報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

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

[編集] 関連項目

English 日本語 中文(简体) 中文(繁體)