19

C++ のreinterpret_castは次のように使用できることを知っています。

float a = 0;
int b = *reinterpret_cast<int*>(&a);

しかし、なぜそれを直接キャストできないのでしょうか?

float a = 0;
int b = reinterpret_cast<int>(a);

error: invalid cast from type 'float' to type 'int'
4

5 に答える 5

38

すべてのreinterpret_cast機能は、渡したメモリを別の方法で読み取ることができるようにすることです。メモリの場所を指定し、そのメモリを自分が要求したかのように読み取るように要求します。これが、ポインターと参照でのみ使用できる理由です。

例として、次のコードを見てみましょう。

#include <iostream>

int main()
{
    float a = 12;
    int b = *reinterpret_cast<int*>(&a);

    std::cout << b;
}

したがって、このコード行をより詳細に分割するには*reinterpret_cast<int*>(&a);:

  1. のアドレスを取るa
  2. reinterpret_castint*
  3. int*を指す を取得しますa
  4. 返されたポインターの値を次のように参照します。int

これを実行するとが表示されます。1094713344その理由は 12 です。IEEE の使用はバイナリfloatとして表されます。0100 0001 0100 0000 0000 0000 0000 0000次に、そのバイナリを取得して として読み取るとunsigned int、最終的には になります1094713344

これが、reinterpret_castが非常に危険であると考えられている理由であり、このタイプの場合に使用してはならない理由です。

メモリを指すポインターがあり、そのメモリを特定の方法で読み取る必要があり、その方法でメモリを読み取ることができることがわかっている場合にのみ使用してください。

于 2013-08-31T06:04:59.570 に答える
12

reinterpret_cast は int をポインターに変換するか、その逆のいずれかのみを取り、追加の同様の規則に従うため、指定した場合に reinterpret_cast を実行することはできません。

そこにこれらのルールの要約があります: http://en.cppreference.com/w/cpp/language/reinterpret_cast

于 2013-08-31T15:36:37.257 に答える
4

なぜ直接キャストできないのですか?

これは純粋な設計上の決定であり、C++ を C よりも型安全にするためだと思います。

reinterpret_cast未定義の動作への近道である型エイリアシングを伴う可能性があるため、非常に危険です。C++ キャストを使用する場合、コンパイラとの契約に「私が何をしているかはわかっています」と署名します。したがって、これらすべての長い演算子名、山かっこ、型ポインタ型変換は、「待ってください。そうしないでください。コード設計に問題がある可能性があります!」と言っています。

また、すべての C++ コンパイラが型エイリアスを許可しているわけではありません (キャストまたは共用体によって達成されます)。

于 2013-08-31T06:17:06.973 に答える