I have the following piece of code in C which works flawlessly. I define NAME_LIST
to facilitate the creation of NAMES_TABLE
.
#include <stdio.h>
#include <stdint.h>
typedef enum {
NAME_1 = 0,
NAME_2 = 1,
NAME_3 = 2,
NAME_4 = 3,
} name_t;
typedef struct {
const uint8_t num_names;
const name_t *name_list;
} name_struct_t;
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define NAME_LIST(...) { \
.num_names = ARRAY_SIZE(((name_t[]){__VA_ARGS__})), \
.name_list = (name_t[]){__VA_ARGS__} \
}
name_struct_t NAMES_TABLE[] = {
NAME_LIST(NAME_1),
NAME_LIST(NAME_2, NAME_3),
NAME_LIST(NAME_4),
};
I want to expand the previous code and add a fixed input argument in the NAME_LIST
MACRO to indicate as specific state to be handled later in the code.
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
typedef enum {
NAME_1 = 0,
NAME_2 = 1,
NAME_3 = 2,
NAME_4 = 3,
} name_t;
typedef struct {
const uint8_t num_names;
const name_t *name_list;
const bool flag;
} name_struct_t;
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define NAME_LIST(flag, ...) { \
.num_names = ARRAY_SIZE(((name_t[]){__VA_ARGS__})), \
.name_list = (name_t[]){__VA_ARGS__} \
.flag = (bool)(flag) \
}
name_struct_t NAMES_TABLE[] = {
NAME_LIST(true, NAME_1),
NAME_LIST(false, NAME_2, NAME_3),
NAME_LIST(true, NAME_4),
};
However, I get the following errors which I am not able to solve.
main.c:36:19: error: expected identifier before numeric constant
36 | NAME_LIST(true, NAME_1),
| ^~~~
main.c:32:10: note: in definition of macro ‘NAME_LIST’
32 | .flag = (bool)(flag) \
| ^~~~
main.c:37:19: error: expected identifier before numeric constant
37 | NAME_LIST(false, NAME_2, NAME_3),
| ^~~~~
main.c:32:10: note: in definition of macro ‘NAME_LIST’
32 | .flag = (bool)(flag) \
| ^~~~
main.c:38:19: error: expected identifier before numeric constant
38 | NAME_LIST(true, NAME_4),
| ^~~~
main.c:32:10: note: in definition of macro ‘NAME_LIST’
32 | .flag = (bool)(flag) \
| ^~~~
Any idea if the extension of the MARCO definition that I did is correct or if there is an alternative way to do that?
It does not like that you use flag
for the macro parameter and the struct
member at the same time. Renaming one of them to something different and adding the missing comma after .name_list = (name_t[]){__VA_ARGS__}
make it work:
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
typedef enum {
NAME_1 = 0,
NAME_2 = 1,
NAME_3 = 2,
NAME_4 = 3,
} name_t;
typedef struct {
const uint8_t num_names;
const name_t *name_list;
const bool flag;
} name_struct_t;
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define NAME_LIST(xyz, ...) { \
.num_names = ARRAY_SIZE(((name_t[]){__VA_ARGS__})), \
.name_list = (name_t[]){__VA_ARGS__}, \
.flag = (bool)(xyz) \
}
name_struct_t NAMES_TABLE[] = {
NAME_LIST(true, NAME_1),
NAME_LIST(false, NAME_2, NAME_3),
NAME_LIST(true, NAME_4),
};