Search code examples
cconstantsinitializer

Initializing constant from constant lookup table


I have a constant lookup table

static const uint32_t lut [] = {0, 20, 100, 350, 560};

I have a struct

typedef struct {
    uint32_t value;
    const char * name;
} strct_t;

And I would like to create global constant instance of that struct

const struct_t def_myname = {
    .value = lut[DEF_MYNAME_ID],
    .name = "myname",
};

but I need to define DEF_MYNAME_ID in other place, so I have this in some header file

#define DEF_MYNAME_ID 3

This can't compile, because of this error initializer element is not constant

There are multiple questions in stackoverflow asking what to do with initializer element is not constant, but none covers my needs.

Is there a way how to do this? For example by defining lut as macro? I don't need it in other place.

Is there something like

#define LUT(a) ...

usabele as const initializer?


Solution

  • Sure, macros can do that. This is actually a safer code, if you pick an index out of range, it won't compile.

    First we define our dictionary

    #define _val0 0
    #define _val1 20
    #define _val2 100
    #define _val3 350
    #define _val4 560
    

    Now we need a PRIMITIVE_CAT to force expansion of the argument of the macro LUT.

    #define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
    

    And finaly, the LUT.

    #define LUT(X) PRIMITIVE_CAT(_val, X)
    

    Now your code.

    #define DEF_MYNAME_ID 3
    const struct_t def_myname = {
        .value = LUT(DEF_MYNAME_ID),
        .name = "myname",
    };