整数型の大きさ

こんにちは、めのんです!

前回に続いて、Cに関する話題を取り上げていきます。
思いつくままダラダラ書いていきますので、ちょっと読みにくいかもしれませんけど、どうかご容赦ください。

今回の話題は「整数型の大きさ」です。
「大きさ」と書きましたが、今回扱うのは整数型の「ビット幅」です。
表現範囲については次回以降でお話しようと考えています。

整数型の分類

Cの整数型は次のような体系になっています。

ここに挙げたほかに、処理系定義の拡張整数型が使えることがあります。
たとえば、GCCの__int128_t型なんかがそれにあたるんだろうと思います(たぶん……。intmax_t型が__int128_t型になっていないのでもしかしたら違うかも)。

Cの整数型には、列挙型を除けば、大きく分けて符号付き整数型と符合無し整数型があります。
char型は符号付きか符合無しかは処理系定義ですので分類上はどちらにも属していないんですけど、実質的には符号付き整数型か符合無し整数型のどちらかだと思っても問題ないと思います。

あと、_Bool型も符合無し整数型の一種です。
整数型または符合無し整数型という場合には_Bool型も含まれるということになります。

符号付き整数型には明示的に「signed」を付けてもかまいません。
signed char型だけはsignedを省略すると別の型になっちゃいますので省略することはできません。

整数型の大きさと大小関係

Cの整数型の大きさ(ビット数やバイト数)はすべて処理系定義です。
char型、signed char型、unsigned char型が1バイトであることは決まっているんですが、1バイトが何ビットかは処理系定義です。

1バイトのビット数が処理系定義だということを納得していただけない方もいらっしゃるようなので、JIS X3010:2003から「バイト」の定義を引用しておきます。

JIS X3010:2003はC99相当なので古いんですけど、日本語で読める規格としては最新ですので、C11以降で追加・変更になった内容以外はこれで十分だと思います。
やっぱり日本語の方が読みやすいですからね。

char型、signed char型、unsigned char型が1バイトだというのは次のように定義されています。

それ以外の整数型については、最小限の表現範囲と型どうしの大小関係が決まっているだけで、具体的に何ビットとか何バイトとかが決まっているわけではありません。
定義されている箇所をまるまる引用すると長いので、一部抜粋しますね。

このあとに、たとえばINT_MAXやINT_MINのような各整数型の最大値と最小値の規定が続きます。
最大値と最小値と書きましたが、処理系はその値以上の絶対値を持つ値に定義しないといけませんので、実際に表現範囲は処理系定義なんです。

これに対して整数型どうしの大小関係は決まっています。
たとえば、short型の大きさはint型を超えてはいけないといったことは決まっているんです。

定義されている場所はJIS X3010:2003のこのあたりです。

このあとも拡張整数型に関することなんかが長々と続きます。

要約すると、整数型の大きさはsigned char型 ≦ short int型 ≦ int型 ≦ long int型 ≦ long long int型で、変換の順位もこれと同じになるということです。

現実の処理系

規格上の話はここまでにして、実際に私たちが遭遇する処理系のことをここからはお話しします。

まず、現在のほとんどの処理系では1バイトは8ビットになっています。
稀に例外はあるみたいですけど、ほとんどの方は一生関わることがないんじゃないでしょうか?

char型が8ビットの処理系では、short型はまず16ビットだと思っていいでしょう。

int型は16ビットか32ビットだと思います。
64ビットの処理系でもint型は32ビットのことがほとんどですし、8ビットの処理系でもint型は16ビットあります(INT_MAXは32767以上、INT_MINは-32767以下でないといけないので)。

long型はいろいろあります。
32ビット以下の処理系ではlong型は32ビットだと思っていいと思います。
稀にlong型が48ビットのDSPなんかがありますが、ほとんど出会うことはないと思います。
64ビットの処理系では、long型は32ビットの場合と64ビットの場合がありますね。

long long型はほとんどの場合64ビットだと思っていいでしょう。

表にまとめるとこんな感じです。

16ビット以下の処理系 32ビット処理系 64ビット処理系
signed char型 8ビット 8ビット 8ビット
short int型 16ビット 16ビット 16ビット
int型 16ビット 32ビット 32ビット
long int型 32ビット 32ビット 32/64ビット
long long int型 64ビット 64ビット 64ビット

何ごとも例外はあって、たとえば16ビットのマイコンのH8Sは、GCCのオプションを指定することでint型が32ビットになることがあります。
モトローラの68000シリーズも16ビットCPUですが、int型は32ビットだったと聞いています。

あと、主にマイコンの処理系ですが、非標準処理も結構あるようで、long long int型が32ビットしかなかったり、(私は見たことがありませんが)int型が8ビットの処理系とかもあるんでしょうね。

大体こんな感じでまとめてみましたが、いかがだったでしょうか?

次回は整数型の表現範囲と内部表現について、もう少し深掘りしてみたいと思います。

それでは!