web-dev-qa-db-ja.com

トラップ表現

  1. Cの「トラップ表現」とは何ですか(いくつかの例が役立つ場合があります)?これはC++に適用されますか?

  2. このコードを考えると...

    _float f=3.5;
    int *pi = (int*)&f;
    _

    ...そしてsizeof(int) == sizeof(float)と仮定すると、fと_*pi_は同じバイナリ表現/パターンを持っていますか?

67
Burt
  1. トラップ表現は、C99(C89ではなくIIRC)で使用されるキャッチオール用語で、型が占めるスペースに収まるビットパターンを表しますが、その型の値として使用すると未定義の動作をトリガーします。定義はセクション6.2.6.1p5(6.2.6のすべてに触手を含む)にあり、長くて混乱を招くため、ここでは引用しません。このようなビットパターンが存在するタイプは、トラップ表現を「持つ」と言われます。トラップ表現を持つためにタイプは必要ありませんが、標準が保証する唯一のタイプnotトラップ表現を持つことは_unsigned char_(6.2.6.1p5、6.2.6.2p1)です。

    標準では、トラップ表現の2つの架空の例を示していますが、どちらも実際のCPUが何年もの間行ってきたものに対応していないため、混乱させることはしません。 goodトラップ表現の例(またonly遭遇する可能性のあるすべてのCPUでハードウェアレベルのトラップ表現と見なされるもの)は、浮動小数点型。 IEC 60559が詳細に動作を指定している場合でも、C99 Annex F(セクション2.1)は、シグナルNaNの動作を明示的に未定義のままにします。

    言及する価値があるのは、ポインタ型areがトラップ表現を持つことが許可されている一方で、nullポインタはnotトラップ表現であることです。 nullポインターは、逆参照またはオフセットされている場合にのみ、未定義の動作を引き起こします。それらに対する他の操作(最も重要なのは、比較とコピー)が明確に定義されていることです。 readトラップ表現を持つ型を使用してトラップ表現を定義すると、未定義の動作が発生します。 (invalidであるが、null以外のポインタがトラップ表現であると見なされるか、または見なされるべきかどうかは、議論の対象です。CPUはそれらをそのように扱いませんが、コンパイラはそうする可能性があります。)

  2. 表示するコードの動作は未定義ですが、これはポインターのエイリアス規則が原因であり、トラップの表現が原因ではありません。これは、同じ表現でfloatintに変換する方法です(あなたが言うようにsizeof(float) == sizeof(int)と仮定)

    _int extract_int(float f)
    {
        union { int i; float f; } u;
        u.f = f;
        return u.i;
    }
    _

    このコードには、C-99でnspecified(未定義ではない)の動作があります。つまり、基本的に、標準では定義されていませんwhat integer valueが生成されますが、some有効な整数値。これはトラップ表現ではありません。コンパイラーは、これを実行していないという前提で最適化することはできません。 (セクション6.2.6.1、第7項。C99の私のコピーには、技術的な正誤表が含まれている可能性があります。私の思い出は、これはwas元の出版物では未定義ですが、TCで未指定に変更されました。)

91
zwol

ポインターへのポインターで浮動小数点数をエイリアスする未定義の動作。

7
Puppy

一般に、一部のプラットフォームでは、非トラップIEEE-754浮動小数点値は整数として表すことができ、問題はありません。ただし、all浮動小数点値が一意の整数表現およびFPUにその値を強制的にロードさせます。

http://www.dmh2000.com/cpp/dswap.shtml からの例)

たとえば、FPデータを操作する場合、エンディアンが異なるCPU間でマーシャリングする必要がある場合、次のことを考えるとよいでしょう。

double swap(double)

残念ながら、コンパイラが入力をFPUレジスタにロードし、それがトラップ表現である場合、FPUは、偶然に異なるビット表現である同等のトラップ表現でそれを書き戻すことができます。

つまり、FP値がいくつかありますが、正しく変換しないと、対応するビット表現がありません(正確には、unionmemcpy経由のchar *または他の標準メカニズム)。

3
MSN