組込みソフト向けC言語コーディング規約|型の定義(構造体、列挙型、ビットフィールドなど)

この記事は約3分で読めます。

この記事では型の定義について記載します。ここではtypedefにて型を定義するときを想定しています。構造体、列挙型、ビットフィールドの定義が主に該当します。typedefは文法上見落としやすい落とし穴が意外に多いので、要注意です。

スポンサーリンク

ビットフィールドに使用する型はsigned intかunsigned intにする(intも不可)

C言語の規格上、ビットフィールドに使える型は、int, signed int, unsigned intのどれかです。また、ビットフィールドの場合はintは符号付か符合無しになるかはコンパイラ依存なので、明示的にsignedもしくはunsignedをつけてください。

違反コード

typedef struct {
        unsigned long  member_a: 2;   // 型がlong.
        int            member_b: 2;   // 符号(signed or unsigned)の指定がない.
} hoge_t;

適合コード

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を使ってください。

違反コード

typedef struct {
        signed    int  member_a: 1;   // 0 か -1のどちらかになる。1にはならない.
} hoge_t;

適合コード

typedef struct {
        unsigned  int  member_a: 1;   // 0 か 1のどちらかになる/
} hoge_t;
スポンサーリンク

列挙型のメンバは、int型で表現できる範囲にする

c言語規格上、列挙子はint型です。int型より大きいデータ(longlong型など)は格納できません。列挙子はint型で収まる範囲にしてください。

違反コード

typedef enum {
	member_0 = 0x1UL,
	member_1 = 0x10UL,
// 略
	member_2 = 0x100000000ULL, // int型(32bit)に収まらない.
} hoge_t;

適合コード

typedef enum {
	member_0 = 0x1UL,
	member_1 = 0x10UL,
// 略
	member_2 = 0x10000000UL, 

} hoge_t;

コメント