2009年03月05日
川俣晶の縁側ソフトウェア技術雑記 total 8869 count

C#には16bit/8bitの加算が存在しない問題

Written By: 川俣 晶連絡先

 ushortを使いまくったコードをC#にポーティングする過程で見落としていた問題に気付きました。

 これまで、C#プログラミングでの整数はほぼ100%に近い水準でintしか使ってこなかったので、盲点でした。

 あまり突っ込んで調べていないので、もし間違いがあればご教示ください。

※ 以下は加算のみを取り上げていますが、他の演算子も同様です。

コンパイルできないコード §

ushort a = 1, b = 2;

ushort c = a + b;

 2行目で発生するエラー内容。

エラー 1 型 'int' を 'ushort' に暗黙的に変換できません。明示的な変換が存在します。(cast が不足していないかどうかを確認してください)

原因 §

 C#に存在する整数の加算演算子は以下のバリエーションだけです。(C#言語仕様より)

  • int operator +(int x, int y);
  • uint operator +(uint x, uint y);
  • long operator +(long x, long y);
  • ulong operator +(ulong x, ulong y);

 従って、"a + b"は最初の"int operator +(int x, int y);"で処理するしかなく、この加算の結果はintになります。intはushortに暗黙的に変換できないので、エラーになります。

対策 §

 たぶん、キャストを入れるしかないでしょう。

ushort c = (ushort)(a + b);

C++/CLIやVisual Basicならキャスト不要? §

 確かにキャストを書かずともコンパイルできますが、実行ファイルを.NET ReflectorでC#形式に逆コンパイルするとしっかりキャストが入っていました。

 つまり、C++/CLIやVisual Basicはキャスト不要なのではなく、コンパイラがキャストを補ってくれているだけでした。

考察 §

 16bit/8bitの加算が用意されないのは、.NET Framework/CLIのアーキテクチャ的な特徴であり、C#の言語仕様はその仕様をストレートにソースコードの書式に反映させたものだと考えられます。従って、C++/CLIやVisual Basicと比較してC#は理不尽な制約が付いている……のではなく、C#では余計なオーバーヘッドが付くケースは明示的なキャストを要求することで、プログラマがそれに気付くチャンスを与えていると見るべきでしょう。

感想 §

 しかし、unsigned shortを大量に使ったC言語のソースをC#へポーティングすると、式がキャストの山になって大変……。