¿Por qué falla este reemplazo de macro anidado?

Estoy tratando de aplicar elX macro concepto, para tener la posibilidad de inicializar todos los miembros de la estructura a un valor predeterminado (no válido) personalizado. Escribo el siguiente código:

#define LIST_OF_STRUCT_MEMBERS_foo \
    X(a) \
    X(b) \
    X(c)

#define X(name) int name;
struct foo {
     LIST_OF_STRUCT_MEMBERS_foo
};
#undef X


#define X(name) -1,
static inline void foo_invalidate(struct foo* in) {
     *in = (struct foo){
     LIST_OF_STRUCT_MEMBERS_foo
     };
}
#undef X

#define X(name) -1,
#define foo_DEFAULT_VALUE  { LIST_OF_STRUCT_MEMBERS_foo }
#undef X

static struct foo test = foo_DEFAULT_VALUE;

Sin embargo, cuando ejecuto el preprocesador, la definición defoo_DEFAULT_VALUE no puede sustituir elX(name) llamadas con-1,

Salida del preprocesador:

struct foo {
     int a; int b; int c;
};

static inline void foo_invalidate(struct foo* in) {
     *in = (struct foo){
     -1, -1, -1, /*Here the substitution worked nicely*/
     };
}

static struct foo test = { X(a) X(b) X(c) }; /*Why this substitution failed?*/

penséLas macros C pueden referirse a otras macros. ¿Sabes por qué falla esa sustitución? ¿Hay algún trabajo alrededor?

Podría vivir confoo_invalidate, pero soy reacio a renunciar a un paso para tener un valor que se utilizará directamente en la inicialización.

Respuestas a la pregunta(3)

Su respuesta a la pregunta