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?

questionAnswers(2)

yourAnswerToTheQuestion