Alternativa padrão ao truque ## __ VA_ARGS__ do GCC?
Existe um bem conhecido problem com argumentos vazios para macros variáveis em C9
exemplo
#define FOO(...) printf(__VA_ARGS__)
#define BAR(fmt, ...) printf(fmt, __VA_ARGS__)
FOO("this works fine");
BAR("this breaks!");
O uso deBAR()
acima está realmente incorreto de acordo com o padrão C99, pois será expandido para:
printf("this breaks!",);
Observe a vírgula à direita - não é viáve
Alguns compiladores (por exemplo: Visual Studio 2010) se livram silenciosamente dessa vírgula final para você. Outros compiladores (por exemplo: GCC) suportam colocar##
em frente de__VA_ARGS__
, igual a
#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?
Agora, o##
versão @ parece bastante bem suportada (pelo menos nas minhas plataformas), mas eu realmente prefiro usar uma solução compatível com os padrõe
Preemptivo: Eu sei que poderia escrever uma pequena função. Estou tentando fazer isso usando macros.
Edita: 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);
Isto adiciona automaticamente uma nova linha às minhas instruções de log BAR (), assumindofmt
é sempre 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íncron