小ネタです。読む価値は特に無いです。
こんな定義の構造体から不要な名前を消していきましょう。
(n
とbit1
は使用するので、消さない。)
typedef struct _Foo {
int n;
int unused;
unsigned bit1:8;
unsigned unusedBit:8;
} Foo;
Foo g_foo;
型定義名(typedef
)を消す
極稀にtypedef
しないと構造体を定義できないと思っている人がいるのですが、必須ではないです。
その場合、型名をstruct
と明示します。(C++であれば省略可能。)
struct Foo {
// ...
};
struct Foo g_foo;
構造体の識別子を消す
構造体の識別子を省略し、無名の構造体に対してtypedef
することで使えます。
typedef struct {
// ...
} Foo;
Foo g_foo;
識別子も型定義名も消す
構造体を一度しか使わない(例えばグローバル変数を定義だけして、後はメンバを参照するだけの)ケースでは、構造体に名前は不要です。
変数と一緒に構造体を定義できます。
struct {
// ...
} g_foo;
以降はこのコード片を使用していきます。
メンバ名を消す
処理系拡張になりますが、型だけ残して、不要なメンバの名前unused
を消せます。
この場合、メンバが存在しないものとして扱われます。(sizeof
のバイト数からも除かれます。)
正直、この文法が役に立つ局面がわかりません。
struct {
int n;
int; // <--
unsigned bit1:8;
unsigned unusedBit:8;
} g_foo;
ビットフィールドのメンバ名を消す
パディングなどで使用しないが調整用に、メンバを追加することがあると思います。
ビットフィールドの不要なメンバの名前unusedBit
を消せます。
この場合、そのビット数は確保され、名前ではアクセスできない領域になります。
struct {
int n;
int unused;
unsigned bit1:8;
unsigned :8;
} g_foo;
// この書き方ができることを最近知ったので、メモとしてこの記事を書きました。
最終的に
こうなります。
慣れていない人は戸惑うかもしれませんが、("メンバ名を消す"以外は)これでも規格に準拠している(はず)です。
struct {
int n;
int;
unsigned bit1:8;
unsigned :8;
} g_foo;