6

Cを使用して組み込みプログラミングを行う場合、高速でメモリ効率が高いため、列挙型と配列を使用してマップを実行することがよくあります。

enum {
    ID_DOG = 0,
    ID_SPIDER,
    ID_WORM,
    ID_COUNT
};
int const NumberOfEyes[ID_COUNT] = {
    2,
    8,
    0
};

問題は、アイテムを追加/削除するときに、間違えて列挙型と配列が同期しなくなることがあることです。初期化子リストが長すぎる場合、コンパイラーはそれを検出しますが、その逆は検出しません。

では、初期化子リストが配列の長さと一致することを確認する、信頼性が高く移植性の高いコンパイル時チェックはありますか?

4

2 に答える 2

9

これはおそらく、X マクロを適用できる状況です。

動物.x

X(DOG,    2)
X(SPIDER, 8)
X(WORM,   0)

foo.c

enum {
#define X(a,b) ID_##a,
#include "animals.x"
#undef X
};

int const numberOfEyes[] = {
#define X(a,b) b,
#include "animals.x"
#undef X
};

これにより、長さが一致することが保証されるだけでなく、注文が常に同期されます。

于 2012-05-04T10:18:37.510 に答える
3

次のようなコンパイル時のアサーションはどうですか?(はい、より複雑なCT_ASSERTマクロがあります。これはアイデアを説明するためのものです。)

#define CT_ASSERT(expr, name) typedef char name[(expr)?1:-1]

enum {
    ID_DOG = 0,
    ID_SPIDER,
    ID_WORM,
    ID_COUNT
};

int const NumberOfEyes[] = {
    2,
    8,
    0
};

CT_ASSERT (sizeof NumberOfEyes/sizeof *NumberOfEyes == ID_COUNT, foo);

これで、NumberOfEyes配列の要素数が。より多いか少ない場合ID_COUNT、これにより。に沿ってエラーが発生しますx.c:15: error: size of array 'foo' is negative。負の配列次元は制約違反であり、Cコンパイラーが診断する必要があります。

于 2012-05-05T20:16:53.320 に答える