【cstdint】C++11で追加された サイズ厳密な整数型

More than 1 year has passed since last update.

はじめに

今までは整数型といえば
char、short、int、long、long long・・・ 等となっており
環境によってビット数が違う場合もあり、不具合の元になってました

C++11には、厳密な整数型があるので、レガシーとの互換性の部分以外は
新しい型を使いましょう

詳細は下記に書いてあります
cpprefjp

型が多すぎる!

int8_t、int16_t、int32_t、int64_t、uint8_t、uint16_t、uint32_t、uint64_t、int_fast8_t、int_fast16_t、int_fast32_t、int_fast64_t、uint_fast8_t、uint_fast16_t、uint_fast32_t、uint_fast64_t、int_least8_t、int_least16_t、int_least32_t、int_least64_t、uint_least8_t、uint_least16_t、uint_least32_t、uint_least64_t、intmax_t、uintmax_t、intptr_t、uintptr_t

多すぎるので分類

[u]intX_t

optional
int32_t とか、一番使ってしまうんだけど、なんと optionalなので
処理系によっては未実装なので その場合は下記の
[u]int_fastX_t か [u]int_leastX_t
を使うことになります・・・
例えば 1バイトが9ビットの処理系では、4Byte=36bit なので、int32_tは定義されない
事が多いんじゃないでしょうか?
かわりに int36_tが定義されるとかされないとか・・・

この型は、厳密なビット数で、パディング無しの大きさで確保されます

sizeof(int8_t) = 1
sizeof(int16_t) = 2
sizeof(int32_t) = 4
sizeof(int64_t) = 8

[u]int_fastX_t

最も実行速度が速くなるバイト数が確保されます(処理系依存)
つまり パディングされます
一例

sizeof(int_fast8_t) = 1
sizeof(int_fast16_t) = 8
sizeof(int_fast32_t) = 8
sizeof(int_fast64_t) = 8

[u]int_leastX_t

格納可能な最も小さいサイズが確保されます(処理系依存)
つまり パディングなし
一例

sizeof(int_least8_t) = 1
sizeof(int_least16_t) = 2
sizeof(int_least32_t) = 4
sizeof(int_least64_t) = 8

[u]intmax_t

最大のサイズの整数型が確保されます
一例

sizeof(intmax_t) = 8

[u]intptr_t

optional
ポインタサイズが確保されます
一例

sizeof(intptr_t) = 8

構造体にしたときのパティングは?

一例を出します

struct
#include<iostream>


struct INT16{
    int16_t n;
    int8_t d;
};

struct FAST16{
    int_fast16_t n;
    int_fast8_t d;
};

struct LEAST16{
    int_least16_t n;
    int_least8_t d;
};



struct PINT16{
    int16_t n;
    int8_t d;
}__attribute__((__packed__));

struct PFAST16{
    int_fast16_t n;
    int_fast8_t d;
}__attribute__((__packed__));

struct PLEAST16{
    int_least16_t n;
    int_least8_t d;
}__attribute__((__packed__));


using namespace std;

int main(){    
    cout << "sizeof(int16_t)=" << sizeof(int16_t) << endl;
    cout << "sizeof(int32_t)=" << sizeof(int32_t) << endl;

    cout << "sizeof(int_fast16_t)=" << sizeof(int_fast16_t) << endl;
    cout << "sizeof(int_fast32_t)=" << sizeof(int_fast32_t) << endl;

    cout << "sizeof(int_least16_t)=" << sizeof(int_least16_t) << endl;
    cout << "sizeof(int_least32_t)=" << sizeof(int_least32_t) << endl;

    cout << "sizeof(intmax_t)=" << sizeof(intmax_t) << endl;
    cout << "sizeof(intptr_t)=" << sizeof(intptr_t) << endl;

    cout << "sizeof(INT16)=" << sizeof(INT16) << endl;
    cout << "sizeof(FAST16)=" << sizeof(FAST16) << endl;
    cout << "sizeof(LEAST16)=" << sizeof(LEAST16) << endl;

    cout << "sizeof(PINT16)=" << sizeof(PINT16) << endl;
    cout << "sizeof(PFAST16)=" << sizeof(PFAST16) << endl;
    cout << "sizeof(PLEAST16)=" << sizeof(PLEAST16) << endl;

    return 1;
}


結果
sizeof(int16_t)=2
sizeof(int32_t)=4
sizeof(int_fast16_t)=8
sizeof(int_fast32_t)=8
sizeof(int_least16_t)=2
sizeof(int_least32_t)=4
sizeof(intmax_t)=8
sizeof(intptr_t)=8
sizeof(INT16)=4
sizeof(FAST16)=16
sizeof(LEAST16)=4
sizeof(PINT16)=3
sizeof(PFAST16)=9
sizeof(PLEAST16)=3

int16_t、int_least16_tは、2バイトとして、ちゃんと切り詰められているが
int_fast16_tは そもそも8バイトとして扱われている
(int_fast8_t は1バイト)
のがわかりますね。