1

以下のコードでは、下の「違法」は未定義であることを知っています (ただし、一部のコンパイラでは許可されています)。これは、ユニオン メンバー「a」がアクティブであり、次にユニオン メンバー「b」から読み取るためです。問題は、「AmILegal」のコードはそれを修正するのか、それとも何か恐ろしいこと、さらにあいまいなことをしているのかということです。memcpy を使用して同じ効果を達成できますか、それとも別の未定義の動作を呼び出していますか?

編集: たぶん、例は十分に明確ではありません。私がしたいのは、他のメンバーをアクティブにすることだけです。したがって、float を int に変更しています。ばかげているように見えますが、実際のケースに近いです。コードの下を読んでください。

(何らかの理由で、ある組合員を別の組合員にコピーすることは許可されていませんか?)

struct Foo
{
    union Bar
    {
        int a[4];
        int b[4];
    };

    void this_is_Illegal()
    {
         a[0]=1;
         a[1]=2;
         a[2]=3;
         a[3]=4;
         std::cout<<b[0]<<b[1]<<b[2]<<b[3];
    }

    void but_is_this_Legal?()
    {
         a[0]=1;
         a[1]=2;
         a[2]=3;
         a[3]=4;

         b[0]=a[0];
         b[1]=a[1];
         b[2]=a[2];
         b[3]=a[3];
         std::cout<<b[0]<<b[1]<<b[2]<<b[3];
    }


    void this_looks_scary_but_is_it?()
    {
         a[0]=1;
         a[1]=2;
         a[2]=3;
         a[3]=4;
         //forget portability for this q, assume sizeof(int)==sizeof(float)
         //maybe memmove works here as well?
         memcpy(b, a, sizeof(int)*4)

         std::cout<<b[0]<<b[1]<<b[2]<<b[3];
    }

};

上記のすべてがあまり役に立たないと思われる場合は、a が実際には float と結合された _m128 であると考えてください[4]。ビット表現は常に正確で正確です。ある時点で、それを実際に使用する必要があり、float の配列としてメイン メモリに保持する必要があります。「コピー命令」は、実際には_m128ユニオンメンバーからfloat [4]メンバーへの_mm_store_psです。したがって、memset に関する質問 - 多分それは私が必要とするもののより正確な例です...

4

2 に答える 2

0

2 番目の関数は完全に正当ですが、ビットを変更せずに int から float への変換を実行するため、同じことは行いません。

正直なところ、私は最初のものに固執します - 動作は技術的に定義されていませんが、それはあなたにとって正しいことをしているだけだと思います.

3 番目のものは、未定義の動作の 1 つの形式を別の形式に切り替えます (任意のバイトを浮動小数点数に書き込んだ後は、何かが起こる可能性があります)。ただし、バイトが実際に有効な浮動小数点値を表していることがわかっている場合は、問題ありません。

于 2012-07-15T09:13:15.710 に答える
-1

this_is_illegal,this_is_legal? 列挙型を使用するほとんど標準的な方法 ;)

しかし、列挙型のために &a と &b が同じアドレスにあり、memcpy は何もしないため、memcpy は機能しません。

&a と &b は同じアドレスにあるため、列挙型を使用していくつかの興味深いことを行うことができます-あなたの場合、浮動小数点数を整数として解釈することは列挙型の組み込み機能ですが、自動キャストはトリガーできません。同じ住所で

プロトコル構造体/列挙型を宣言するのに役立つため、 attribute ((packed))を見たいと思うかもしれません

于 2012-07-15T09:20:31.037 に答える