Hay un problema bien conocido con argumentos vacíos para macros variables en C99.
ejemplo:
#define FOO(...) printf(__VA_ARGS__)
#define BAR(fmt, ...) printf(fmt, __VA_ARGS__)
FOO("this works fine");
BAR("this breaks!");
El uso de lo BAR()
anterior es de hecho incorrecto según el estándar C99, ya que se expandirá a:
printf("this breaks!",);
Tenga en cuenta la coma final: no funciona.
Algunos compiladores (por ejemplo: Visual Studio 2010) se deshacerán silenciosamente de esa coma final por usted. Otros compiladores (p. Ej .: GCC) admiten poner ##
delante de este __VA_ARGS__
modo:
#define BAR(fmt, ...) printf(fmt, ##__VA_ARGS__)
Pero, ¿hay alguna forma que cumpla con los estándares para obtener este comportamiento? ¿Quizás usando múltiples macros?
En este momento, la ##
versión parece bastante compatible (al menos en mis plataformas), pero prefiero usar una solución que cumpla con los estándares.
Preventivo: Sé que podría escribir una pequeña función. Estoy tratando de hacer esto usando macros.
Editar : Aquí hay un ejemplo (aunque simple) de por qué me gustaría usar BAR ():
#define BAR(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)
BAR("here is a log message");
BAR("here is a log message with a param: %d", 42);
Esto agrega automáticamente una nueva línea a mis declaraciones de registro BAR (), suponiendo fmt
que siempre sea una C-cadena entre comillas dobles. NO imprime la nueva línea como un printf () separado, lo cual es ventajoso si el registro está almacenado en línea y proviene de múltiples fuentes de forma asincrónica.
__VA_OPT__
palabra clave. Esto ya ha sido "adoptado" por C ++, por lo que espero que C haga lo mismo. (no sé si eso significa que fue acelerado en C ++ 17 o si está configurado para C ++ 20)
BAR
lugar deFOO
en primer lugar?