Há um problema conhecido com argumentos vazios para macros variadas em C99.
exemplo:
#define FOO(...) printf(__VA_ARGS__)
#define BAR(fmt, ...) printf(fmt, __VA_ARGS__)
FOO("this works fine");
BAR("this breaks!");
O uso BAR()
acima é realmente incorreto de acordo com o padrão C99, uma vez que se expandirá para:
printf("this breaks!",);
Observe a vírgula à direita - não é viável.
Alguns compiladores (por exemplo: Visual Studio 2010) se livram silenciosamente dessa vírgula final para você. Outros compiladores (por exemplo: GCC) suportam colocar ##
na frente __VA_ARGS__
, assim:
#define BAR(fmt, ...) printf(fmt, ##__VA_ARGS__)
Mas existe uma maneira compatível com os padrões para obter esse comportamento? Talvez usando várias macros?
No momento, a ##
versão parece bastante bem suportada (pelo menos em minhas plataformas), mas eu prefiro usar uma solução compatível com os padrões.
Preemptivo: Eu sei que poderia escrever uma pequena função. Estou tentando fazer isso usando macros.
Edit : Aqui está um exemplo (embora simples) de por que eu gostaria de 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);
Isso adiciona automaticamente uma nova linha às minhas instruções de log BAR (), supondo que fmt
sempre seja uma string C com aspas duplas. NÃO imprime a nova linha como um printf () separado, o que é vantajoso se o log estiver em buffer de linha e proveniente de várias fontes de forma assíncrona.
__VA_OPT__
palavra - chave. Isso já foi "adotado" pelo C ++, então espero que o C siga o exemplo. (não sei se isso significa que ele foi acelerado em C ++ 17 ou se ele é definido para C ++ 20 embora)
BAR
vez de,FOO
em primeiro lugar?