Detectar presencia o ausencia de argumentos en una macro C

¿Cómo se puede definir un IFARGS(YES, NO, ...) macro de C IFARGS(YES, NO, ...) modo que al invocar a IFARGS sin argumentos adicionales se produzca NO , y al invocar a IFARGS con uno o más argumentos se IFARGS YES ?

Tengo una respuesta utilizando GCC (ver más abajo), pero preferiría una para C99 si es posible (o una prueba de su imposibilidad).

En C99 es posible detectar si un argumento de macro está vacío, pero hacer que sea robusto contra todas las probabilidades que puedan aparecer en ese argumento (los argumentos que se están expandiendo, contienen () y cosas por el estilo) es difícil. Mi paquete de macros P99 implementa tal cosa, para que no tenga que preocuparse demasiado. Con eso tu macro se puede implementar como

 #define IFARGS(YES, NO, ...) P99_IF_EMPTY(__VA_ARGS__)(YES(__VA__ARGS__))(NO()) 

Como su nombre lo indica, P99 solo se basa en las características de C99 para eso.

 #define GET(_0, _1) _0 // Return the first of two arguments #define GET_(_0, _1) _1 // Return the second of two arguments #define JOIN(_0, _1) _0 ## _1 // Concatenate two arguments #define EJOIN(_0, _1) JOIN(_0, _1) // Expand macros and concatenate #define FIRST(_, ...) _ // Truncate everything after first comma #define EFIRST(_) FIRST(_) // Expand argument and pass to FIRST #define REST(_0, ...) __VA_ARGS__ // Remove everything before first comma #define GET_GET(...) \ EJOIN(GET, EFIRST(REST(,,##__VA_ARGS__ _))) // Branch between GET and GET_ #define IFARGS(YES, NO, ...) GET_GET(__VA_ARGS__)(YES, NO) 

Tenga en cuenta que si esto fuera posible en C99, entonces sería posible simular ##__VA_ARGS__ , así:

 #define PREPEND_COMMA(...) , __VA_ARGS__ #define NO_COMMA() #define PREPEND_COMMA_IF_NONEMPTY(...) IFARGS(PREPEND_COMMA, NO_COMMA, __VA_ARGS__)(__VA_ARGS__) 

Luego, cualquier instancia de , ##__VA_ARGS__ podría reemplazarse por PREPEND_COMMA_IF_NONEMPTY(__VA_ARGS__) .