コンパイラが C/C で変数の自己初期化を許可するのはなぜですか?

Susan Sarandon
リリース: 2024-11-16 06:50:03
オリジナル
527 人が閲覧しました

Why does the compiler allow self-initialization of variables in C/C  ?

Uninitialized Variables in Self-Initialization: Behavior and Standards

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 サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート