Inappropriate array detection & # 8596; enum initializers

When doing inline programming with C, I find many times that I am making cards with an enumeration and an array, because they are fast and memory efficient.

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

The problem is that sometimes when I add / remove items, I make a mistake, and the listing and array go out of sync. If the list of initializers is too long, the compiler will detect it, but not vice versa.

So, is there a reliable and portable compile-time check so that the list of initializers matches the length of the array?

+6
source share
2 answers

How about a compile time statement as follows? (Yes, there are more complex CT_ASSERT macros, this illustrates the idea.)

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

Now that the NumberOfEyes array has more or less elements than ID_COUNT , it will ID_COUNT an error along xc:15: error: size of array 'foo' is negative . Negative array sizes are a constraint violation that must be diagnosed with any C compiler.

+3
source

Perhaps this could be a situation where macros X can be applied.

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

This not only ensures matching lengths, but also that orders are always kept in sync.

+9
source

Source: https://habr.com/ru/post/914887/


All Articles