sizeof(char)==sizeof(int)となる処理系の奇妙な世界

C/C++では、汎整数型のサイズは最小表現範囲と相対的な大小関係が決まっているだけで、それ以外は処理系定義になります。char型は少なくとも8ビット以上あれば何ビットでもよく、char型のサイズが1バイトということになります。int型も16ビット以上であれば何ビットでもかまいません。このことから、char型とint型のサイズがともに16ビットとか64ビットとかでもまったくかまわないということになります。

理屈の上ではわかっていても、具体的な処理系と関わることがなければ実感がわいてきません。私の場合、もう長い間、TOPPERSプロジェクトに関わってきた関係上、JSPカーネルが対応しているテキサス・インスツルメンツ製のDSPが16ビットのchar型を持っているため、決して机上の空論ではなく、移植性に関する重要な問題であるととらえてきました。

というわけで、今回、char型とint型のサイズが同じ処理系で起こるさまざまな奇妙な現象について考えてみることにします。

char型とint型のサイズが同じということは、unsigned char型、そしてchar型が符号付きの場合はchar型の表現範囲をint型が網羅していないことになります。その結果、char型が符号無しの場合であっても文字定数はint型でなければなりませんので、char型であれば正の値であっても文字定数では負の値になることがあります。直接比較した場合には、通常の算術型変換によってunsigned int型にそろえられるため大きな問題はなさそうです。しかし、いったんlong型にキャストして比較する場合には問題が生じます。

また、isalpha関数の引数はunsigned charの表現範囲かEOFでなければなりませんが、仮引数がint型なので仕様が破綻しています。fputcやungetcについても同様です。fgetc(getcやgetcharも同様)については、EOFか文字を返すということなので、限りなく黒に近いグレーということになります。

要するに、unsigned char型および符号無しのchar型を汎整数拡張するとint型ではなくunsigned int型になってしまうことに大きな問題があります。標準ライブラリは、明らかに汎整数拡張によってint型になることを前提として仕様が決められているようですから。

この記事のトラックバックURL:

http://www.kijineko.co.jp/trackback/586