I am trying to apply the X Macro concept, in order to have the possibility to initialize all struct members to a custom default (invalid) value. I write the following code:<
You might also try to check the output of expanded macros. If you are using gcc as a compiler, gcc -E <filename> >> full_src.txt'
shall help. More details are here: Seeing expanded C macros
You might like the undef-free version of X_Macros,
it reduces the necessary care taken with defining and undefining around each use
and is better suited for definition in a header und useage in multiple code files:
#define LIST_OF_STRUCT_MEMBERS_foo(mode) \
X_##mode(a) \
X_##mode(b) \
X_##mode(c)
#define X_struct(name) int name;
#define X_list(name) -1,
#define foo_DEFAULT_VALUE { LIST_OF_STRUCT_MEMBERS_foo(list) }
struct foo {
LIST_OF_STRUCT_MEMBERS_foo(struct)
};
static inline void foo_invalidate(struct foo* in) {
*in = (struct foo){
LIST_OF_STRUCT_MEMBERS_foo(list)
};
}
static struct foo test = foo_DEFAULT_VALUE;
Output (gcc -E):
struct foo {
int a; int b; int c;
};
static inline void foo_invalidate(struct foo* in) {
*in = (struct foo){
-1, -1, -1,
};
}
static struct foo test = { -1, -1, -1, };
Let's pretend that we are the preprocessor and encountering the line:
static struct foo test = foo_DEFAULT_VALUE;
Pass 1:
static struct foo test = { LIST_OF_STRUCT_MEMBERS_foo };
Pass 2:
static struct foo test = { X(a) X(b) X(c) };
Pass 3: Nothing to expand as X
is undefined on this line.
One workaround could be defining a const variable (possibly but not necessarily static
) to be used as default value:
#define X(name) -1,
static const struct foo foo_DEFAULT_VALUE = { LIST_OF_STRUCT_MEMBERS_foo };
#undef X
Which generates:
static const struct foo foo_DEFAULT_VALUE = { -1, -1, -1, };