Как использовать атрибут формата GCC printf с вариабельными шаблонами C ++ 11?

У меня есть класс C ++, который является интерфейсом для системы журналирования. Его функция регистрации реализована с использованием вариабельных шаблонов C ++ 11:

template <typename... Args>
void Frontend::log(const char *fmt, Args&&... args) {
  backend->true_log(fmt, std::forward<Args>(args)...);
}

Каждый бэкэнд регистрации реализует свою собственную версиюtrue_log, который, помимо прочего, использует перенаправленные параметры для вызоваvsnprintf, Например.:

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..
}

Все отлично работает, и я счастлив.

Теперь я хочу добавить статическую проверку наlog() параметры: в частности, я хотел бы использовать атрибут формата GCC printf.

Я начал с пометкиlog() функция с__attribute__ ((format (printf, 2, 3))) (какthis является первым «скрытым» параметр, мне нужно сместить индексы параметров на один). Это не работает, потому что, если происходит сбой с ошибкой компиляции:

error: args to be formatted is not ‘...’

Затем я попытался добавить тот же атрибут кtrue_log() функция. Он компилируется, но проверка ошибок на самом деле не выполняется: я пытался перейти кlog() некоторые недопустимые комбинации формат / переменная, и не было выдано предупреждение. Может быть, этот вид проверки «слишком поздний» или, другими словами, информация о переменной была потеряна в цепочке вызовов?

В крайнем случае, если я аннотировалlog() с__attribute__ ((format (printf, 2, 0))), Я получаю предупреждения о неправильных строках формата, но не будет выдана диагностика для недопустимых комбинаций формат / переменная.

Подводя итог проблемы:how can I have full format checking from GCC if I use C++11's variadic templates?

Ответы на вопрос(2)

Ваш ответ на вопрос