Détection des tableaux incompatibles initialiseurs d’énumération

Lorsque je fais de la programmation intégrée en C, je me suis souvent retrouvé à faire des cartes avec enum et array, car elles sont rapides et utilisent beaucoup de mémoire.

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

Le problème est que, parfois, lors de l’ajout / la suppression d’éléments, je commets des erreurs, l’énumération et le tableau ne sont plus synchronisés. Si la liste d’initialisation est trop longue, le compilateur la détectera, mais pas l’inverse.

Donc, y at-il une vérification fiable et portable de la compilation lors de la compilation de la liste des initialiseurs avec la longueur de la masortingce?

Qu’en est-il d’une assertion de temps de compilation comme celle-ci? (Oui, il existe des macros CT_ASSERT plus élaborées. C’est pour illustrer cette idée.)

 #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); 

Désormais, lorsque le tableau NumberOfEyes a plus ou moins d’éléments ID_COUNT , cela provoquera une erreur le long de xc:15: error: size of array 'foo' is negative . Les dimensions de tableau négatives sont une violation de contrainte qui doit être diagnostiquée par tout compilateur C existant.

C’est peut-être une situation où les macros X pourraient être appliquées.

animaux.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 }; 

Cela garantit non seulement que les longueurs correspondent, mais également que les commandes sont toujours synchronisées.