In the realm of programming, it is often a point of concern to use uninitialized variables. However, in the case of an uninitialized variable being used as its own initializer, a unique scenario arises.
Consider the following code:
int main(void) { int i = i; }
驚くべきことに、このコードは C99、C11、C 11 などの標準を使用して、clang/gcc/clang /g でコンパイルできます。さらに、-Wall -Wextra オプションを指定しても、コンパイラは警告を出力しません。
しかし、コードを int i = i 1; に変更し、-Wall オプションを指定すると、次のような警告が表示される場合があります。
why.c:2:13: warning: variable 'i' is uninitialized when used within its own initialization [-Wuninitialized] int i = i + 1; ~ ^ 1 warning generated.
それでは、コンパイラがこのコードを許可するのはなぜでしょうか。また、C/C 標準ではこれについてどのように規定されているのでしょうか。
コンパイラの許容
変数 i は自己初期化時に未初期化なので、その時点では 非特定値 を持ちます。非特定値とは、未指定値 または トラップ表現 のいずれかです。
実装が整数型の詰め込みビットをサポートしており、非特定値がトラップ表現になっている場合、それを使用すると 未定義の動作 になります。
実装に整数の詰め込みビットがない場合、値は単に 未指定 になり、未定義の動作 は生じません。
標準の規定
C11 標準のセクション 6.3.2.1p2 には、次のように詳しく説明されています。
lvalue が自動ストレージ期間のオブジェクトを表し、そのオブジェクトが register ストレージクラスで宣言できた (アドレスが取得されたことがない) 可能性があり、そのオブジェクトが初期化されていない (初期化子で宣言されておらず、使用する前に割り当てが実行されていない) 場合、その動作は未定義です。
したがって、i のアドレスを取得したことがない場合は、未定義の動作が発生します。それ以外の場合は、上記の記述が適用されます。
以上がコンパイラが C/C で変数の自己初期化を許可するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。