C++講座 その5 サイズとバイトオーダー
サイズ
32bit CPUでWindows系の環境では各型は次のようなサイズになっている。
型名 | サイズ(byte) |
---|---|
char | 1 |
short | 2 |
int | 4 |
long | 4 |
float | 4?(後日確認) |
double | 8 |
「一般的な」としたのは、これらのサイズはCPUやOSの環境に依存するため。64bit環境では上表とは異なる値になる。
C++言語により規定されているのは、次のルールのみで「intはNバイト」という規定はない。
1≡sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) 1 <= sizeof(bool) <= sizeof(long) sizeof(char) <= sizeof(wchar_t) <= sizeof(long) sizeof(float) <= sizeof(double) <= sizeof(long double) sizeof(N) ≡ sizeof(signed N) <= sizeof(unsigned N) // Nはchar,short,int,longのいずれか
C/C++での最大値・最小値の定義
limitsヘッダに各型の最大値、最小値の定数値が定義されている。
#include<limits> #include<iostream> using namespace std; #define cout_limit(T) cout << #T << "," << sizeof(T) << "," << numeric_limits<T>::min() << "," << numeric_limits<T>::max() << endl int main() { cout_limit(bool); cout_limit(char); cout_limit(short); cout_limit(int); cout_limit(long); cout_limit(float); cout_limit(double); cout_limit(long double); return 0; }
バイトオーダー
short以上の2バイト以上の型の場合、CPUによって値の配置順序が異なる。
リトルエンディアン
Intel系のCPUの場合、リトルエンディアンという順序で値は配置され、次のようになる。
short a = 0;
aが0x1000番地に配置されたと仮定すると、次のように値は設定される。
アドレス | 値 |
---|---|
0x1000 | 0 |
0x1001 | 0 |
a = 1;
アドレス | 値 |
---|---|
0x1000 | 1 |
0x1001 | 0 |
a=255;
アドレス | 値 |
---|---|
0x1000 | FF |
0x1001 | 0 |
a = 256;
アドレス | 値 |
---|---|
0x1000 | 0 |
0x1001 | 1 |
これは16進数でメモリをダンプ出力した際、見た目と逆に表示される。(左の桁の方が小さい)
値 | ダンプ(16進数) |
---|---|
0 | 00 00 |
1 | 01 00 |
255 | FF 00 |
256 | 00 01 |
ビッグエンディアン
SH2,SH4や今はなきサンマイクロシステムズのSPARCで採用されている。 リトルエンディアンとは逆順に値が設定される。
short a = 0;
aが0x1000番地に配置されたと仮定すると、次のように値は設定される。
アドレス | 値 |
---|---|
0x1000 | 0 |
0x1001 | 0 |
a = 1;
アドレス | 値 |
---|---|
0x1000 | 0 |
0x1001 | 1 |
a=255;
アドレス | 値 |
---|---|
0x1000 | 0 |
0x1001 | FF |
a = 256;
アドレス | 値 |
---|---|
0x1000 | 1 |
0x1001 | 0 |
こちらは16進数でメモリをダンプ出力した際、見た目通りに表示される。(右の桁の方が小さい)
値 | ダンプ(16進数) |
---|---|
0 | 00 00 |
1 | 00 01 |
255 | 00 FF |
256 | 01 00 |
移植性とネットワークバイトオーダー
同じ環境のみでデータを授受している場合、バイトオーダーは問題ない(送信元、受信先ともに同じバイトオーダーのため)。しかし、バイトオーダーの異なる環境で授受する場合は、どちらかに統一する必要がある。例えばTCP/IPの場合、一般的にビッグエンディアン(ネットワークバイトオーダー)に合わせる。 参考 Wikipedia エンディアン
2014/2/15 補足
エンディアンはバイトのみならず、ビットにも存在する。これもCPU等の環境により異なるので移植の際に問題となる。