21
#include <stdio.h>
int main() {
    int c = c;
    printf("c is %i\n", c);
    return 0;
}

と呼ばれる整数変数を定義し、cその値をそれ自体に割り当てています。しかし、これはどのようにコンパイルすることができますか?cまだ初期化されていないので、その値をそれ自体にどのように割り当てることができますか?プログラムを実行すると、が表示されますc is 0

コンパイラが変数にスペースを割り当てるアセンブリコードを生成していると想定しています(コンパイラがステートメントcに遭遇したとき)。int c次に、初期化されていないスペースにあるジャンク値を取得して、に割り当てますc。これは何が起こっているのですか?

4

5 に答える 5

30

以前の回答でこれを引用したことを覚えていますが、現時点では見つかりません。

C++03§3.3.1/1:

名前の宣言のポイントは、完全な宣言子(8節)の直後で、初期化子(存在する場合)の前にあります...

したがって、変数cは、初期化子部分の前でも使用できます。

編集:申し訳ありませんが、Cについて具体的に質問されました。そこに同等の行があると確信していますが。ジェームズ・マクネリスはそれを見つけました:

C99§6.2.1/7:構造体、共用体、または列挙型タグではない識別子は、「宣言子の完了直後に開始するスコープを持ちます」。宣言子の後に初期化子が続きます。

于 2010-07-13T16:50:36.210 に答える
11

あなたの推測は正確に正しいです。int c変数のスタックにスペースをプッシュします。この変数は、パーツに対して読み取られ、再書き込みされますc = c(ただし、コンパイラーはそれを最適化する場合があります)。コンパイラは値をとしてプッシュしています0が、これが常に当てはまるとは限りません。

于 2010-07-13T16:52:29.847 に答える
5

初期化されていない値を使用することは未定義の動作です(§C99J.2「自動保存期間のあるオブジェクトの値は不確定なときに使用されます」)。したがって、鼻の悪魔からc = 0、Nethackのプレイまで、何でも起こり得ます。

于 2010-07-13T16:51:21.347 に答える
2

C仕様は、変数が0、0.0、または""または''に初期化されることを保証しません。

これはコンパイラの機能であり、それが発生することを突き止める必要はありません。

私はいつもIDE/コンパイラをそのことについて警告するように設定しています。

于 2010-07-13T18:27:57.750 に答える
2

cが初期化されました!

これは1行のコードですが、実際には最初にcを初期化し、次にcを割り当てています。コンパイラがcをゼロに初期化しているのは幸運です。

于 2010-07-13T16:48:34.077 に答える