C言語規約シリーズです。今回は型の定義についてです。
この記事では型の定義について記載します。ここではtypedefにて型を定義するときを想定しています。
構造体、列挙型、ビットフィールドの定義が主に該当します。
typedefは文法上見落としやすい落とし穴が意外に多いので、要注意です。
ビットフィールドに使用する型はsigned intかunsigned intにする(intも不可)#
C言語の規格上、ビットフィールドに使える型は、int, signed int, unsigned intのどれかです。
また、ビットフィールドの場合はintは符号付か符号無しになるかはコンパイラ依存なので、明示的にsignedもしくはunsignedをつけてください。
違反コード#
1
2
3
4
| typedef struct {
unsigned long member_a: 2; // 型がlong.
int member_b: 2; // 符号(signed or unsigned)の指定がない.
} hoge_t;
|
適合コード#
1
2
3
4
| typedef struct {
unsigned int member_a: 2;
signed int member_b: 2; // 符号ありだと明示的に指定.
} hoge_t;
|
1bit幅のビットフィールドの型はunsigned intを使う(signed intは不可)#
signed int型は最上位1bitが符号をあらわすbitになります。
1bit幅のビットフィールドをsigned intにした場合、その1bitは符号bitになってしまうので、つまり0か-1かしか表現できません。
ですので、0,1を表現するために、1bit幅のビットフィールドの型はunsigned intを使ってください。
違反コード#
1
2
3
| typedef struct {
signed int member_a: 1; // 0 か -1のどちらかになる。1にはならない.
} hoge_t;
|
適合コード#
1
2
3
| typedef struct {
unsigned int member_a: 1; // 0 か 1のどちらかになる/
} hoge_t;
|
列挙型のメンバは、int型で表現できる範囲にする#
c言語規格上、列挙子はint型です。int型より大きいデータ(long long型など)は格納できません。列挙子はint型で収まる範囲にしてください。
違反コード#
1
2
3
4
5
6
| typedef enum {
member_0 = 0x1UL,
member_1 = 0x10UL,
// 略
member_2 = 0x100000000ULL, // int型(32bit)に収まらない.
} hoge_t;
|
適合コード#
1
2
3
4
5
6
7
| typedef enum {
member_0 = 0x1UL,
member_1 = 0x10UL,
// 略
member_2 = 0x10000000UL,
} hoge_t;
|
Note
下記のC言語コーディング規約シリーズも併せてご参照ください