この記事では型の定義について記載します。ここでは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;
他のコーディング規約は下記のページからたどれます。ぜひ見てみてくださいね
C言語コーディング規約
組込みソフト(ファームウェア)向けのc言語コーディング規約を書いています。これをみておけばcの文法的なミス減らせるかなと思います。また、C言語のベテランの方もひとつくらいは新しい発見があると思います。ぜひご参考ください! コーディング規約一...
コメント