aが初期化されていない場合、a^aやa-aは未定義の動作なのでしょうか?
質問
このプログラムを考えてみましょう。
#include <stdio.h>
int main(void)
{
unsigned int a;
printf("%u %u\n", a^a, a-a);
return 0;
}
未定義の動作なのでしょうか?
表面上は
a
は初期化されていない変数です。つまり、未定義の挙動を指しているわけです。しかし
a^a
と
a-a
は
0
のすべての値に対して
a
というのは、少なくとも私はそう思っています。動作がうまく定義されていることを主張する何らかの方法がある可能性はありますか?
どのように解決するのですか?
C11で。
-
6.3.2.1/2 によれば、以下の場合、明示的に未定義です。
a
はそのアドレスが取られることはありません (以下引用) - トラップ表現(アクセスするとUBが発生する)である可能性があります。6.2.6.1/5:
ある種のオブジェクト表現は、オブジェクト型の値を表す必要はありません。
Unsigned intはトラップ表現を持つことができます(例えば、15精度ビットと1パリティビットを持つ場合、アクセスする
a
にアクセスすると、パリティ障害を引き起こす可能性があります)。
6.2.4/6では、初期値として 不定 であり、3.19.2におけるその定義は 不特定値またはトラップ表現 .
さらに:C11 6.3.2.1/2 で、Pascal Cuoq によって指摘されたように。
lvalueが自動保存期間のオブジェクトを指定する場合、そのオブジェクトはレジスタ保存クラスで宣言された可能性があります(アドレスが取られたことはありません)。 レジスタ保存クラスで宣言された(そのアドレスが取られたことのない)自動保存期間のオブジェクトを指定し、そのオブジェクトが初期化されていない(そのアドレスが取られたことのない)場合。 が初期化されていない(イニシャライザで宣言されておらず、使用前に代入が行われていない)場合、動作は次のようになります。 の場合、その動作は未定義です。
これは文字型に対する例外を持たないので、この節は前の議論に優先するように見えます; accessing
x
にアクセスすることは、たとえトラップ表現が存在しなくても、即座に未定義となります。この節は
は C11 に追加されました。
は、実際にレジスタのトラップステートを持っている Itanium CPU をサポートするために追加されました。
トラップ表現がないシステム。
しかし、もし私たちが
&x;
を投げることで、6.3.2.1/2 の反論はもはや適用されず、トラップ表現を持たないことが知られているシステム上にいる場合はどうでしょうか。 その場合、その値は
未指定値
.
の定義は
不特定値
の定義は少し曖昧ですが、3.19.3では以下のように明確化されています。
DR 451
と結論付けています。
- 説明された条件下で初期化されていない値は、その値を変更するように見えることがあります。
- 不確定な値に対して行われる操作は、結果として不確定な値を持つことになります。
- ライブラリ関数は、不定値で使用された場合、未定義の挙動を示すようになります。
- これらの回答は、トラップ表現を持っていないすべての型に適切です。
この解答のもとでは
int a; &a; int b = a - a;
の結果は
b
はまだ不確定な値を持っています。
不定値がライブラリ関数に渡されない場合、我々はまだ未定義の動作の領域にいることに注意してください(未定義の動作ではありません)。結果は奇妙なものになるかもしれません、例えば
if ( j != j ) foo();
は foo を呼び出すことができますが、悪魔は鼻腔に鎮座したままでなければなりません。
関連
-
警告:符号付き整数式と符号なし整数式の比較 [-Wsign-compare]
-
[解決済み] C言語の書式指定子 %ul と %lu の違いは何ですか?
-
[解決済み] Linux Socket write() によるBad File Descriptor C
-
[解決済み] C言語の**はどういう意味ですか?
-
[解決済み] C言語では「?」演算子は何をするのですか?
-
[解決済み] 未定義の動作とシーケンスポイント
-
[解決済み] 未定義、未指定、および実装で定義された動作
-
[解決済み] なぜC言語では構造体を頻繁にtypedefする必要があるのですか?
-
[解決済み】なぜこれらのコンストラクトはプリインクリメントとポストインクリメントを使用して未定義の動作をしているのでしょうか?
-
[解決済み】f(i = -1, i = -1)の挙動が未定義なのはなぜ?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
構造体の配列--[エラー] '['トークンの前に一次式があることが予想される
-
ポインタ定数および定数ポインタ
-
[解決済み] Valgrind が初期化されていないバイトについて警告する
-
[解決済み] stdinとSTDIN_FILENOの違いは何ですか?
-
[解決済み] CコードでEOFを表現する?
-
[解決済み] C言語のコードで「:-!」とは何ですか?
-
[解決済み] 配列の場合、なぜ a[5] == 5[a] になるのでしょうか?
-
[解決済み] 配列のすべてのメンバーを同じ値で初期化するには?
-
[解決済み] C言語標準に準拠した構造体の初期化方法
-
[解決済み] (なぜ)初期化されていない変数を使用することは未定義の動作なのですか?