-3

いくつかの悪いコードが int 値を float アドレスに設定したとしましょう。一般に、その int 値を取得するにはどうすればよいですか?

4

2 に答える 2

2

この回答に関する注意:以下のコードは、を使用して (int用に予約されたメモリ位置に を格納したというfloat)問題をエミュレートし、再度reinterpret_castを使用して問題を解決しreinterpret_castます。これは、厳密なエイリアシング規則(3.10/10 C++ 標準) を破ります。これは、オブジェクトの実際の型と一致しない型の (g)lvalue を介してオブジェクトにアクセスすることを示しています (ある意味で一致します)。未定義の動作を呼び出します。

このため、以下に示すコードは使用しないでください。解決策、つまり を使用することreinterpret_castは、少なくとも危険です (ただし、多くの場合は機能します)。正しい解決策については、Steve Jessop の回答を参照してください。私の間違いを指摘してくれてありがとう(コメントを参照)。


元の回答:
値が格納されているアドレスがあり、そのアドレスが整数アクセス用に正しく配置されている場合、これに使用できるはずですreinterpret_cast:

int main()
{
  /* An integer and an uninitialized float: */
  int original = 45;
  alignas(int) alignas(float) float f;

  float *p = &f;

  /* "Erroneously" putting an int into the address of the float: */
  *reinterpret_cast<int*>(p) = original;

  /* Retrieving the int (this is what you were looking for): */
  int retrieved = *reinterpret_cast<int*>(p);

  std::cout << "Original: " << original
            << ", Stored float: " << f
            << ", Retrieved: " << retrieved
            << std::endl;
  return 0;
}

(上記で使用されているキーワードalignasは C++11 のものです。コンパイラがそれを受け入れない可能性があります。いずれにせよ、コードのその部分は問題をエミュレートするための私の方法であり、ソリューションの本質的な部分ではありません。)

于 2013-01-24T06:52:23.467 に答える
1

答えreinterpret_cast<int*>は厳密なエイリアシングに違反しており、未定義の動作をしています。

定義された動作でそれを行いたい場合:

int read_int_from_float(const float &f) {
    int result;
    std::memcpy(&result, &f, sizeof(result));
    return result;
}

これはそれを確認した後であり、同じサイズfloatを持っています。int同じ配置である必要はありません。

于 2013-01-24T09:12:52.387 に答える