Как использовать атрибут GCC 'format'?
Вот небольшой кусочек кода:
#include <stdio.h>
#include <stdarg.h>
void MyPrintf(char const* format, va_list args);
void MyVariadicPrintf(char const* format, ...);
void MyPrintf(char const* format, va_list args)
{
vprintf(format, args);
}
void MyVariadicPrintf(char const* format, ...)
{
va_list args;
va_start(args, format);
MyPrintf(format, args);
va_end(args);
}
int main(int, char*)
{
MyVariadicPrintf("%s" /* missing 2nd argument */);
return 0;
}
Я компилирую его с помощью GCC 4.0, запускаю Xcode на Mac OS X Leopard.
-Wformat и -Wmissing-format-attribute включены.
Этот код выдает предупреждение в строке 9 (вызовvprintf
), предполагая, чтоMyPrintf
может использовать атрибут 'format':
функция может быть возможным кандидатом для атрибута формата 'printf'
Поэтому я добавляю атрибут следующим образом (не уверен, что это правильно):
void MyPrintf(char const* format, va_list args) __attribute__((format(printf, 1, 0)));
Предыдущее предупреждение исчезает, и то же самое предупреждение теперь появляется в строке 16 (вызовMyPrintf
), предполагая, чтоMyVariadicPrintf
может использовать атрибут «формат».
Поэтому я добавляю атрибут таким образом (уверен, что на этот раз это правильно):
void MyVariadicPrintf(char const* format, ...) __attribute__((format(printf, 1, 2)));
И теперь я получаю ожидаемое предупреждение в строке 22 (позвонитеMyVariadicPrintf
):
слишком мало аргументов для формата
Я сделал это правильно?Я заметил, что наMyPrintf
объявление, если я удалю часть атрибута, я все равно получу предупреждение о разыскивании в строке 22. Я также заметил, что в этой части атрибута изменение индекса с 1 на 2 не даст никакого предупреждения или ошибки. Какой из них правильный и какова цель атрибута этой функции?Если я добавлю следующую функциюMyVariadicPrintfT
и называть это (специализируется сchar
), Я получу предупреждение, предлагающее использовать атрибут 'format' для этой функции. Я думаю, что это невозможно, потому чтоformat
Аргумент зависит от типа шаблона. Я прав?
template<typename Type>
void MyVariadicPrintfT(Type const* format, ...)
{
va_list args;
va_start(args, format);
MyPrintf(format, args);
va_end(args);
}
Последнюю документацию по GNU можно найти по адресуgnu.org.
Параметры предупреждения находятся враздел 3.8 (ищите "-Wmissing-format-attribute").
Атрибуты функции находятся враздел 6.30 (ищите «формат (архетип, строковый индекс, первый для проверки)»).
Благодарю.