reinterpret_cast 演算子 (C++ のみ)

reinterpret_cast 演算子は、無関係の型の間の変換を扱います。

構文図を読む構文図をスキップする
reinterpret_cast 演算子の構文 

>>-reinterpret_cast--<--Type-->--(--expression--)--------------><

C++11右不等号括弧の機能により、2 つの連続する > トークンの代わりに >> トークンを使用して、template_idreinterpret_cast 演算子の Type として指定することができます。詳しくは、クラス・テンプレート (C++ のみ)を参照してください。C++11

reinterpret_cast<Type>(expression) の結果は、以下のいずれかの値のカテゴリーに属します。
  • Type が左辺値参照型である場合C++11または関数型に対する右辺値参照である場合C++11reinterpret_cast<Type>(expression) は左辺値です。
  • C++11Type がオブジェクト型に対する右辺値参照である場合、reinterpret_cast<Type>(expression) は xvalue です。C++11
  • それ以外すべての場合は、reinterpret_cast<Type>(expression) は、C++11(prvalue)C++11 右辺値です。
reinterpret_cast 演算子は、引数と同じビット・パターンをもっている、新規の型の値を作成します。 const または volatile 修飾をキャストすることはできません。 以下の変換を明示的に実行することができます。
  • ポインターから、それを保持するのに十分に大きい任意の整数型へ
  • 整数値または列挙型から、ポインターへ
  • 関数を指すポインターから、別の型の関数を指すポインターへ
  • オブジェクトを指すポインターから、別の型のオブジェクトを指すポインターへ
  • メンバーを指すポインターから、別のクラスまたは型のメンバーを指すポインターへ。 ただし、メンバーの型が、両方とも関数型か両方ともオブジェクト型である場合。

NULL ポインター値は、宛先型の NULL ポインター値へ変換されます。

T と左辺値式 x がある場合に、左辺値参照に関する以下の 2 つの式は構文が異なりますが、意味は同じです。
  • reinterpret_cast<T&>(x)
  • *reinterpret_cast<T*>(&(x))
C++11T と左辺値式 x がある場合に、右辺値参照に関する以下の 2 つの式は構文が異なりますが、意味は同じです。
  • reinterpret_cast<T&&>(x)
  • static_cast<T&&>(*reinterpret_cast<T*>(&(x)))
C++11

ポインターの一方の型をポインターの非互換型であるとする再解釈は、通常無効です。reinterpret_cast 演算子は、他の名前付きキャスト演算子と同様に、C スタイル・キャストよりもはっきりとわかりやすく、 明示的キャストが可能な強い型宣言を持つ言語の中で矛盾した部分が強調されます。

C++ コンパイラーは、全部ではないがほとんどの違反を検出し、修正します。 プログラムがコンパイルされても、そのソース・コードが、 完全には正しくない場合があるということを覚えておくことは重要です。 プラットフォームによっては、パフォーマンスの最適化は、標準の別名割り当て規則に厳密に準 拠して行われます。C++ コンパイラーは、型ベースの別名割り当て違反についてヘルプしようと試みますが、 すべての可能なケースを検出することはできません。

次の例は、別名割り当て規則に違反しています。 しかし、C++ または K&R C で最適化せずにコンパイルすると、期待どおりに実行されます。 また、C++ でも最適化して正常にコンパイルできますが、必ずしも期待どおりには実行されません。 問題の 7 行目は、x の古いまたは未初期化の値を印刷してしまいます。

1  extern int y = 7.;
2
3  int main() {
4       float x;
5       int i;
6       x = y;
7       i = *(int *) &x;
8       printf("i=%d. x=%f.¥n", i, x);
9  }

次のコードの例は、キャストが 2 つの異なるファイルにまたがっているので、 コンパイラーが検出すらもできない、誤ったキャストを含んでいます。

1  /* separately compiled file 1 */
2      extern float f;
3      extern int * int_pointer_to_f = (int *) &f; /* suspicious cast */
4
5  /* separately compiled file 2 */
6      extern float f;
7      extern int * int_pointer_to_f;
8      f = 1.0;
9      int i = *int_pointer_to_f;           /* no suspicious cast but wrong */
8 行目において、int i = *int_pointer_to_f がロード元としている同じオブジェクトを、 f = 1.0 が保管先としていることを、コンパイラーが知る方法はありません。