Como usar o atributo de formato printf do GCC com modelos variadic do C ++ 11?
Eu tenho uma classe de C ++ que é o frontend para um sistema de log. Sua função de logging é implementada usando os modelos variadic do C ++ 11:
template <typename... Args>
void Frontend::log(const char *fmt, Args&&... args) {
backend->true_log(fmt, std::forward<Args>(args)...);
}
Cada back-end de logging implementa sua própria versão detrue_log
, que, entre outras coisas, usa os parâmetros encaminhados para chamarvsnprintf
. Por exemplo.:
void Backend::true_log(const char *fmt, ...) {
// other stuff..
va_list ap;
va_start(ap, fmt);
vsnprintf(buffer, buffer_length, fmt, ap);
va_end(ap);
// other stuff..
}
Tudo funciona muito bem e sou feliz.
Agora, quero adicionar uma verificação estática nolog()
parâmetros: especificamente, eu gostaria de usar o atributo de formato printf do GCC.
Eu comecei marcando olog()
função com__attribute__ ((format (printf, 2, 3)))
(Comothis
é o primeiro parâmetro "oculto", eu preciso deslocar os índices de parâmetro em um). Isso não funciona, porque se falhar com um erro de compilação:
error: args to be formatted is not ‘...’
Então, tentei adicionar o mesmo atributo aotrue_log()
função. Ele compila, mas nenhuma verificação de erro é realmente executada: tentei passar paralog()
algumas combinações inválidas de formato / variável e nenhum aviso foi emitido. Talvez esse tipo de verificação seja "tarde demais" ou, em outras palavras, a informação sobre a variável tenha sido perdida na cadeia de chamadas?
Como último recurso, se eu anotasselog()
com__attribute__ ((format (printf, 2, 0)))
, Eu receberia avisos sobre cadeias de formato incorretas, mas nenhum diagnóstico seria emitido para combinações inválidas de formato / variável.
Resumindo o problema:Como posso ter a verificação de formato completo do GCC se eu usar os modelos variadic do C ++ 11?