web-dev-qa-db-ja.com

C ++でのPODタイプのデフォルトの初期化

一部の [〜#〜] pod [〜#〜] 変数はデフォルトで初期化されますが、そうでないものもあります。 (PODタイプには、intfloat、ポインター、共用体、PODタイプの配列、PODタイプの構造体などが含まれます。)

スコープとストレージクラスはPODタイプのデフォルトの初期化にどのように影響しますか?

具体的には、次のうちどれが暗黙的に初期化されますか。

  • 自動ストレージを備えたローカル変数
  • 静的ローカル変数
  • 静的グローバル変数
  • 外部変数
  • newで割り当てられた変数
  • クラスのPODメンバー(コンストラクターでの明示的な初期化なし)

これらの状況のいくつかに関連する既存の質問があることは知っていますが、包括的ではありません(特定の状況にのみ対処します)。

14
QuasarDonkey

自動保存期間のローカル変数は自動的に初期化されていません。初期化されていない変数を使用すると未定義の動作が生成されるため、冗長な場合でも変数を明示的に初期化することをお勧めします。

ゼロで初期化されているPODタイプについて、C++ 03標準.6.2非ローカルオブジェクトの初期化状態:

§1静的ストレージ期間(3.7.1)のオブジェクトは、他の初期化が行われる前にゼロ初期化(8.5)でなければなりません。ゼロ初期化と定数式による初期化は、まとめて静的初期化と呼ばれます。他のすべての初期化は動的初期化です。定数式(5.19)で初期化された静的ストレージ期間を持つPODタイプ(3.9)のオブジェクトは、動的初期化が行われる前に初期化される必要があります。

したがって、静的ストレージ期間(スコープが何であれ)のPODタイプはゼロで初期化されることが標準で保証されています。

クラスのPODメンバー(コンストラクターでの明示的な初期化なし)

この状況は12.6.2ベースとメンバーの初期化で説明されており、(選択されたパーツ)は次のように述べています。

特定のnonstaticデータメンバーまたは基本クラスがmem-initializer-idによって名前が付けられていない場合(mem-initializer-listがない場合を含む)コンストラクターにはctor-initializerがないため)、次のようになります。

—エンティティが非静的データメンバー ...であり、エンティティクラス非PODクラスの場合、エンティティはデフォルトで初期化 =(8.5).。

それ以外の場合、エンティティは初期化されません .. ..

クラスXのコンストラクターの呼び出しが完了した後、Xのメンバーがコンストラクターのmem-initializersで指定されておらず、default-initializedでもvalue-initializedでも、コンストラクターの本体の実行中に値が指定されていない場合、 メンバーの値は不確定です。

例:

class C
{
public:
    C(int x, int z) : x(x), z(z) { }
    int x, y, z;
};

int main(void)
{
    C* c = new C(1,3);
    std::cout << c->y; // value of y is undetermined !!!
}
15
LihO

PODについてのみ話している場合は、どこかで定義する必要があるため、ローカルおよびグローバル統計および外部変数のみです。

newで割り当てられたPODも初期化されます時々-初期化を明示的にすると:

int* x = new int();

intがそれを指すように0に初期化されたxを作成します。

int* x = new int;

xは初期化されていないintを指します。

時々--PODクラスメンバー-明示的に初期化できます(コンストラクターに含まれていなくても):

struct X
{
   int x;
};

X x;        //x.x is not initialized
X y = X();  //y.x is 0
8
Luchian Grigore