キャストだらけのプログラム

型制約の厳しい言語では必要に応じて強制的な型変換(キャスト: Cast)が必要となり、それがまたバグの温床であるらしいのです。

C言語では簡単に型を(  )でくくるにことにより、このキャストが可能です。しかし、これはあまりにも簡単過ぎ、安易に行ってしまいますし、後でバグとりの時に発見しにくい、という副作用もあるらしいのです。

これに対して、C++ではややこしい構文をわざと使用せねばなりません。これにより、プログラマに対して心理的圧迫を与え、何とかしてキャストを使用せずにもっとスマートなプログラムを書くように暗黙的に強制します。また、バグ発見もこの構文を探すことにより、より容易にできる、このような利点が言われています。

こんなこと、自分ごときが書く小さなプログラムでは関係無いよ、そのように今まで思っていましたが、先の、DHTをサーチして、そのアドレスを可変配列Vectorに収納し、後から、そのアドレス近傍の内容を表記するプログラムを書いた時に、そのキャストの嵐に会いました。

  1.     std::vector <u_short *> address;
  2.     // u_charへのポインタをいれるvectorを宣言した
  3.     u_short *buffer = new u_short[bufSize/2]; 
  4.     // ワードずつ確保なので半分
  5.     u_short * const bufTop = buffer;
  6.     u_short * const bufEnd = bufTop + bufSize/2;
  7.     u_short *bufPntr = bufTop;
  8.     // 動き回るポインターを先頭にセット
  9.     fp.read(reinterpret_cast<char *> (buffer), bufSize);
  10.     // ここではバイト単位でしか指定できないのでキャストする
  11.     while (bufPntr < bufEnd) {
  12.         if (*bufPntr == 0xC4FF) {
  13.             // Little Endianに注意!!
  14.             // DHT tagにヒットした
  15.             address.push_back(bufPntr);
  16.         }
  17.         bufPntr++;
  18.     }
  19.     fp.close();
  20.     u_char * bufferByte;
  21.     // これでvector<u_short *> addressにDHTアドレスが格納された
  22.     std::vector<u_short *>::iterator it;;
  23.     for (it = address.begin(); it != address.end(); ++it) {
  24.         std::cout << std::hex << (int)*reinterpret_cast<u_char *> (*it) << ” “;
  25.         std::cout << static_cast<int>(*(reinterpret_cast<u_char *> (*it) + 1)) << ” “;
  26.         std::cout << static_cast<int>(*(reinterpret_cast<u_char *> (*it) + 2)) << ” “;
  27.         std::cout << static_cast<int>(*(reinterpret_cast<u_char *> (*it) + 3)) << ” “;
  28.         std::cout << static_cast<int>(*(reinterpret_cast<u_char *> (*it) + 4)) << ” “;
  29.         std::cout << static_cast<int>(*(reinterpret_cast<u_char *> (*it) + 5)) << ” “;
  30.         std::cout << static_cast<int>(*(reinterpret_cast<u_char *> (*it) + 6)) << ” “;
  31.         std::cout << (int)*(reinterpret_cast<u_char *> (*it) + 7) << ” “;
  32.         std::cout << (int)*(reinterpret_cast<u_char *> (*it) + 8) << ” “;
  33.         std::cout << (int)*(reinterpret_cast<u_char *> (*it) + 9) << ” “;
  34.         std::cout << (int)*(reinterpret_cast<u_char *> (*it) + 10) << std::endl;
  35.         std::cout << ” : “ << (int)*(bufferByte + 4) << std::endl;
  36.     }

こんなことになると、流石に自分の書いているプログラムは改良の余地がたくさんあるぞ、ということを思い知らされますよね。要するに、バイト単位で動かねばならないところを、わざわざワード単位で書いているからこんなことになるのでしょう。流石に31行から35行ではたまらなくなり、C言語のキャスト構文 (int)を static_cast<int>のかわりに使ってしまいました。
これもC++の新しいキャスト構文のお蔭様様ですかね。

投稿者: (KAMAKURA & SAPPORO)Dr_Radialist

Expert Interventional Cardiologist and Amateur Computer Programmer

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です