-3

次のコードを検討してください。

int l;
int k;
for (int i=0; i < 2; ++i)
{
    int j;
    if (i == 0) l = j;
    if (i == 1) k = j;
}
assert (l == k);

主張は成り立つか?興味深い点は、初期化されていない変数が異なる反復で異なる値を取ることができるかどうかです。

LLVMをいじってみると、アサーションが実際に保持されていることが示唆されます.これは実際に標準によって保証されているのでしょうか、それとも未定義であり、LLVMコンパイラが実装する方法で発生するのでしょうか?

4

1 に答える 1

3

あなたがやろうとしていることに関して:の値jは不確定です。宣言されたときにたまたまスタック上にあるものであるため、アサーションは必ずしも保持されません。


編集:j割り当てられるたびにスタック上の同じ場所にある可能性が高いため、値の予想される動作は何ですか?

それが同じであるという事実は、実装の事実です。標準は次のように述べています。

6.2.4可変長配列型を持たないそのようなオブジェクトの場合、その有効期間は、関連付けられているブロックへのエントリから、そのブロックの実行が何らかの方法で終了するまで延長されます。(囲まれたブロックに入るか、関数を呼び出すと、現在のブロックの実行が中断されますが、終了しません。) ブロックに再帰的に入ると、オブジェクトの新しいインスタンスが毎回作成されます。オブジェクトの初期値は不定です。オブジェクトに初期化が指定されている場合は、ブロックの実行で宣言に到達するたびに実行されます。そうしないと、宣言に到達するたびに値が不確定になります。

不確定です。

編集2:それはC標準でした。C++ から:

6.7自動保存期間 (3.7.2) を持つ変数は、それらの宣言ステートメントが実行されるたびに初期化されます。ブロックで宣言された自動保存期間を持つ変数は、ブロックの終了時に破棄されます (6.6)。

于 2013-02-02T23:48:29.957 に答える