cenumsassert

Checking enum values at compile time


I'd like to check static initalizers at compile time. I'm implementing the macro CASSERT() from this question.

Now, I have this "strange" situation

typedef enum
{
    EQADC_CHAN_A_00 = 0,
    EQADC_CHAN_A_01,
    EQADC_CHAN_A_02,
    EQADC_CHAN_A_03,
    EQADC_CHAN_A_04,
    ...                 // Others
    EQADC_CHAN_MAX      // EQADC_CHAN_MAX = 62

} eQadc_tInputBiosId;

And I have a structure initialized like this:

const t_EQADC_Pin_Config EQADC_xPinConfig[EQADC_CHAN_MAX] = {
    { 123 },  /* EQADC_CHAN_A_00 */
    { 321 },  /* EQADC_CHAN_A_01 */
    ...       /* Others */
};

What is strange (to me...) is that the following statement

CASSERT(( sizeof(EQADC_xPinConfig)/sizeof(EQADC_xPinConfig[0]) ) != 62 );

works fine, and actually "passes" (i.e. compiles without errors). Instead, this:

CASSERT(( sizeof(EQADC_xPinConfig)/sizeof(EQADC_xPinConfig[0]) ) != EQADC_CHAN_MAX );

does not (i.e. it actually generates an assertion, and stops the compiler.

Trying to figure out why this happens, I think that the problem is related to the value of EQADC_CHAN_MAX, that is not known at compile time, being an enum value. If this is the case, I still can't understand why this declaration

const t_EQADC_Pin_Config EQADC_xPinConfig[EQADC_CHAN_MAX]

actually instantiates the correct size for the array... Any help on how I can (better) implement this is really appreciated.

Edit: my fault. The correct syntax is

CASSERT(( sizeof(EQADC_xPinConfig)/sizeof(EQADC_xPinConfig[0]) ) == EQADC_CHAN_MAX );

Furthermore, pay attention as declaring the array this way:

const t_EQADC_Pin_Config EQADC_xPinConfig[EQADC_CHAN_MAX] = { Initializers ....}

actually allocates the size of EQADC_CHAN_MAX elements, even if the number of initialized elements is not actually correct. So, the right way to implement this is:

const t_EQADC_Pin_Config EQADC_xPinConfig[] = { Initializers ....}
CASSERT(( sizeof(EQADC_xPinConfig)/sizeof(EQADC_xPinConfig[0]) ) == EQADC_CHAN_MAX );

Solution

  • Have a look at this thread that discusses how sizeof is evaluated at compilation while directives are evaluated before compilation, so directives that depend on sizeof will not work.

    If that doesn't help then can you run your compilation step with the -p option, or whatever it is for your compiler, to produce pre-processor output? That might clarify why the predicate in your 2nd assertion doesn't evaluate to what you expect.

    Also, why are you asserting that the size of that array is not 62?