static_castとreinterpret_castの違いについて試してみた

昨日のネタのうち、キャスト関連は思い込みとか理解不足なところがあったので、実際に動かしてみた。

//---------------------------------------------------------------------------
#include <iostream>
#pragma hdrstop

#include <tchar.h>
//---------------------------------------------------------------------------

#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
  double a = 123.4567;
//int i0 = reinterpret_cast<int>(a); // error!!! [BCC32 エラー] File1.cpp(12): E2031 'double' から 'int' へのキャストはできない
  int& i1 = reinterpret_cast<int&>(a);
  int* i2 = reinterpret_cast<int*>(&a);
  int  i3 = static_cast<int>(a);
//int* i4 = static_cast<int*>(&a);  // error!!! [BCC32 エラー] File1.cpp(12): E2031 'double *' から 'int *' へのキャストはできない
  int* i5 = (int*)&a;
  int& i6 = (int&)a;

  std::cout << sizeof(a) << std::endl;
  std::cout << sizeof(int) << std::endl;
  std::cout << i1 << std::endl;
  std::cout << *i2 << std::endl;
  std::cout << i3 << std::endl;

  return 0;
}
//---------------------------------------------------------------------------

感じとして、Cスタイルのキャストは何が何でも変換。結果についてはお構いなし。reinterpret_castはポインタ同士のように互いに関連性がありそうならばキャストする。static_castは暗黙の型変換が許されればキャストする。

上記コード例のint*とdouble*の場合、reinterpret_castは互いにポインタなのでOKだけど、static_castは型そのものが違うので、暗黙の型変換が存在しなくてエラー。「プログラミング言語 C++ 第3版」の170ページあたりと実際の実行結果(C++Builder XEとVC++2008で確認 )から解釈すると、こんな感じなのかな…。