Jak używać atrybutu formatu printf GCC z szablonami zmiennymi C ++ 11?
Mam klasę C ++, która jest frontendem dla systemu rejestrowania. Jego funkcja rejestrowania jest zaimplementowana przy użyciu różnych szablonów C ++ 11:
template <typename... Args>
void Frontend::log(const char *fmt, Args&&... args) {
backend->true_log(fmt, std::forward<Args>(args)...);
}
Każdy backend rejestrowania implementuje własną wersjętrue_log
, że między innymi wykorzystuje wywołane parametry do wywołaniavsnprintf
. Na przykład.:
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..
}
Wszystko działa świetnie, a ja jestem szczęśliwy.
Teraz chcę dodać kontrolę statycznąlog()
parametry: konkretnie chciałbym użyć atrybutu formatu printf GCC.
Zacząłem od oznaczenialog()
funkcja z__attribute__ ((format (printf, 2, 3)))
(tak jakthis
jest pierwszym „ukrytym” parametrem, muszę przesunąć indeksy parametrów o jeden). To nie działa, ponieważ w przypadku niepowodzenia błąd kompilacji:
error: args to be formatted is not ‘...’
Następnie próbowałem dodać ten sam atrybut dotrue_log()
funkcjonować. Kompiluje się, ale w rzeczywistości nie wykonuje się sprawdzania błędów: próbowałem przejść dolog()
niektóre niepoprawne kombinacje formatu / zmiennej i nie wydano żadnego ostrzeżenia. Może ten rodzaj kontroli jest „za późno”, czyli innymi słowy, informacja o zmiennej została utracona w łańcuchu połączeń?
W ostateczności, jeśli dodam adnotacjęlog()
z__attribute__ ((format (printf, 2, 0)))
, Otrzymywałbym ostrzeżenia o błędnych ciągach formatów, ale nie wydano by żadnej diagnostyki dla nieprawidłowych kombinacji formatów / zmiennych.
Podsumowując problem:jak mogę mieć pełne sprawdzanie formatu z GCC, jeśli korzystam z szablonów różnicowych C ++ 11?