12

この投稿によると、不確定な値は次のとおりです。

3.17.2
1 indeterminate value
either an unspecified value or a trap representation

Googleによると、不確定の定義は次のとおりです。

  • 不明、既知、または確立されていない
  • 疑わしいままです。漠然。

フリーディクショナリーによると、決定可能なものは次のとおりです。

  • 決定可能な

メリアム・ウェブスターによると、(特定のコンテキストで)決定することは次のとおりです。

  • 調査、推論、または計算によって調べる、または決定を下すこと

したがって、常識的には、不確定な値はコンパイル時には不明ですが、実行時には完全に決定可能であると規定されています。たとえば、そのメモリ位置を占有するものは何でもいつでも読み取ることができます。

それとも私が間違っていますか?もしそうなら、なぜですか?

編集: 明確にするために、不確定な値が不確定であることを私に納得させようとしたユーザーとの激しい議論になったことに関連してこれを投稿します。

EDIT 2:明確にするために、「決定可能」とは、安定した値または使用可能な値を意味するものではありません。初期化されていないメモリのガベージ値であっても、そのガベージの値を決定できます。つまり、その値を決定しようとしても、何もしないのではなく、何らかの値が得られるということです。したがって、この値は、まだ不確定な値のストレージとして割り当てられたメモリから取得する必要があります。任意の値を考え出すためだけに、コンパイラが実際に乱数ジェネレータなどを使用することは非常に疑わしいです。

4

6 に答える 6

17

不確定であるという事実は、最初の読み取りで予測できないことを意味するだけでなく、安定であることが保証されていないことも意味します。これは、初期化されていない同じ変数を 2 回読み取っても、同じ値が生成されるとは限らないことを意味します。このため、その値を読み取って実際に「決定」することはできません。( 2004 年からのこの主題に関する最初の議論についてはDR#260を参照し、2014 年にその立場を再確認したDR#451を参照してください。)

たとえば、(メモリ位置ではなく) 特定の時間枠内aで CPU レジスタを占有するように変数が割り当てられる場合があります。R1最適な変数からレジスタへの割り当てスケジュールを確立するために、「オブジェクトの有効期間」の言語レベルの概念は十分に正確ではありません。CPU レジスタは、「値の有効期間」というより正確な概念に基づいて、最適化コンパイラによって管理されます。変数に確定値が割り当てられると、値の有効期間が始まります。値の有効期間は、以前に割り当てられた確定値が最後に読み取られたときに終了します。値の有効期間は、変数が特定の CPU レジスタに関連付けられている期間を決定します。R1b. 初期化されていない変数aをその値の有効期間外に読み取ろうとすると、実際には variable が読み取らbれる可能性があり、これはアクティブに変化している可能性があります。

このコードサンプルでは

{
  int i, j;

  for (i = 0; i < 10; ++i)
    printf("%d\n", j);

  for (j = 0; j < 10; ++j)
    printf("%d\n", 42);
}

iコンパイラは、とのオブジェクトの有効期間がj重複していても、値の有効期間がまったく重複していないことを簡単に判断できます。つまり、iとの両方jが同じ CPU レジスタに割り当てられる可能性があります。iそのようなことが起こった場合、最初のサイクルが反復ごとに絶えず変化する の値を出力することが簡単にわかるかもしれません。これは、不確定であるという価値観と完全に一致していjます。

この最適化は必ずしも CPU レジスタを必要としないことに注意してください。別の例として、貴重なスタック スペースの保持に関心のあるスマートな最適化コンパイラは、上記のコード サンプルの値の有効期間を分析し、それを次のように変換する場合があります。

{
  int i;

  for (i = 0; i < 10; ++i)
    printf("%d\n", <future location of j>);
}

{
  int j;

  for (j = 0; j < 10; ++j)
    printf("%d\n", 42);
}

変数ij使用し、異なる時間にメモリ内の同じ場所を占有します。iこの場合、最初のサイクルは繰り返しごとに の値を出力することになるかもしれません。

于 2013-06-30T21:16:31.977 に答える
11

不確定な値を 2 回連続して読み取ると、2 つの異なる値が得られる場合があります。さらに、不確定な値を読み取ると、トラップ表現の場合に未定義の動作が呼び出されます。

DR#260で、C 委員会は次のように書いています。

不確定な値は、任意のビット パターンで表すことができます。C 標準では、指定された値を表すビットの 2 つの検査で同じビット パターンが観察されるという要件は規定されていません。ただし、それぞれの場合に観察されるパターンが値の有効な表現になるということだけです。

[...] 私たちの回答に到達する際に、不確定な値に対して不変のビット パターンを要求すると、最適化の機会が減少することに注意しました。たとえば、不定値を含むメモリがページ アウトされた場合、不確定値の実際のビット パターンを追跡する必要があります。これはオプティマイザにとって不必要な制約のように思えますが、プログラマにとっては何の補償もありません。

于 2013-06-30T21:18:05.330 に答える
5

C90 標準では、不確定な場所からの読み取りが未定義の動作であることを明確にしました。最近の標準はそれほど明確ではありませんが (不確定なメモリは「未指定の値またはトラップ表現のいずれか」です)、コンパイラは依然として不確定な場所の読み取りが未定義の動作である場合にのみ許される方法で最適化します。初期化されていない変数の整数を 2 倍すると、おかしな結果になることがあります。

要するに、いいえ、何が起こっても不確定なメモリを占有することはできません。

于 2013-06-30T21:20:09.883 に答える
1

標準がindeterminateのような用語を導入する場合、それは規範的な用語です。辞書の定義ではなく、標準の定義が適用されます。これは、不定値が未指定の値またはトラップ表現にすぎないことを意味します。不確定の通常の英語の意味は適用されません。

標準で定義されていない用語でさえ、規範的な参照を含めることで規範的なものになる場合があります。たとえば、C99 標準のセクション 2 には、ISO/IEC 2382-1:1993, Information technology — Vocabulary — Part 1: Fundamental terms というドキュメントが規範的に含まれています。.

これは、用語が標準で使用され、テキストで定義されていない場合 (イタリック体で導入され、説明されておらず、用語セクションで与えられていない場合) にもかかわらず、上記の語彙ドキュメントの単語である可能性があることを意味します。その場合、その規格の定義が適用されます。

于 2014-08-02T13:51:38.323 に答える
-1

標準の作成者は、不確定な値を読み取るコードが標準と矛盾するような動作をしないようにするために実装にコストがかかる場合があることを認識していました (たとえば、a の値がuint16_t正しくない可能性があります)。多くの実装は0..65535、標準が要求するよりも多くのケースで不定値がどのように動作するかについて、有用な動作保証を安価に提供できますが、ハードウェア プラットフォームとアプリケーション フィールドの間の変動は、単一の保証セットがすべての目的に最適ではないことを意味します。標準は、この問題を単に実装の品質の問題としてパントします。

標準は確かに、ガベージ品質だが準拠する実装が、たとえば初期化されていないもののほとんどすべての使用を処理できるようにするuint16_t鼻の悪魔を解放するための招待状として。さまざまな目的に適した高品質の実装が同様に機能するかどうかについては何も述べていません (それでも、それらの目的に適した高品質の実装と見なされます)。意図しないデータ漏えいの可能性をトラップするように設計された実装に対応する必要がある場合、オブジェクトの値が最終的に無視されるが、情報が漏えいしないことを実装が証明できない場合には、オブジェクトを明示的にクリアする必要があります。同様に、高品質の汎用実装が行うべきことではなく、低品質だが準拠している実装が許可されていることに基づいて設計された「オプティマイザー」を持つ実装に対応する必要がある場合、そのような「オプティマイザー」

于 2018-08-28T20:13:25.453 に答える