12

私は値の初期化とデフォルトの初期化の理解を新たにしていて、これに出くわしました

struct C {
    int x;
    int y;
    C () { }
};

int main () {
    C c = C ();
}

どうやらこれはUBです

C()の場合、xおよびyメンバーを初期化できるコンストラクターがあるため、初期化は行われません。したがって、C()をcにコピーしようとすると、未定義の動作が発生します。

理由は理解できたと思いますが、よくわかりません。誰かが詳しく説明してもらえますか?

これもUBだということですか?

int x; x = x;

ちなみに、値の初期化に関して、以下はゼロであることが保証されていますか?

int x = int ();
4

3 に答える 3

13

最初の例の動作は未定義です。これは、デフォルトのコンパイラー生成コピーコンストラクターがメンバーごとintのコピーを実行し、トラップ値が含まれている可能性があり、トラップ値を読み取ってコピーすると、プログラムがクラッシュする可能性があるためです。

実際には、これが実際にクラッシュすることは想像できません。コンパイラはほぼ確実にコピーを最適化します。最適化されなかった場合でも、トラップ値をチェックせずにコピーする特別なビット単位のコピーを使用する可能性があります。(C ++では、バイトをコピーできることが保証されています。)

2番目のケースでも、未定義の動作です。この場合、コピー構造ではなく割り当てがあり、コンパイラーがそれを最適化する可能性は低くなります。(最初の例には割り当てはなく、コピーの作成のみです。)

第三に、はい。括弧が空の初期化子(およびそれをオーバーライドするユーザー定義のデフォルトの初期化子がない)は、最初にゼロの初期化を実行します(静的な有効期間を持つ変数の場合とまったく同じです)。

于 2012-02-06T16:49:51.700 に答える
1

undefined behaviorの値はc持っていますが、これは実際にはないと思いますunspecified values。つまり、これらの不特定の値を使用することにならない限り、プログラムの動作は明確に定義されています。条件付きまたは印刷などで使用する場合、結果は定義されません。しかし、私はこのプログラムが奇妙なことをすることを許されているとは思いません。

組み込み型でデフォルトのコンストラクターを使用することに関して、これは型のゼロ値を生成することが保証されています。つまり0、整数、0.0浮動小数点型などです。これは、コンストラクターのない型のメンバーにも適用されます。コンストラクターができたら、自分でコンストラクターを使わずにメンバーを作成する必要があります。

于 2012-02-06T16:50:18.737 に答える
-1

いいえ。ほとんどのコンパイラは変数の設定を最適化しますが、そうでないコンパイラはxの値を変更しません。次のコードと同じです。

int x = 0;
x = 0;

2行目が実行されないわけではなく、何も実行されないだけです。

于 2012-02-06T16:38:46.817 に答える