GCC: __attribute__ ((format (printf, x, y)), похоже, не работает, когда функция вызывается с использованием макроса с переменным числом аргументов

0

Версия GCC ntoarm-gcc (GCC) 4.4.2

Я добавил атрибуты формата 'printf' ко всем моим функциям, которые завершают printf() и co. Они отлично работают, но только при вызове функций с использованием вариационного макроса.

class Log { [...]
    void log_fmt(LogLevel level, const std::string& funcName, const char_t * const logFormatStr, ...)  __attribute__ ((format (printf, 4, 5)));
[...] };

Неправильный прямой вызов, например

log.log_fmt(Info, "test", "wrong %u", "type");

дает предупреждение:

format '%u' expects type 'unsigned int', but argument 5 has type 'const char*'

Тот же неправильный вызов с использованием макроса не дает никакого предупреждения:

#define LOGI(MSG, ...) log.log_fmt(Info, __func__, (MSG), __VA_ARGS__)
LOGI("wrong %u", "type");

Могу ли я получить предупреждения и в этом случае? Я допустил ошибку или это намеренное поведение?

  • 0
    макросы не проверяют тип. они просто отвечают
  • 0
    Вы пробовали параметры -Wall и -Wextra для gcc
Теги:
gcc
macros
variadic

1 ответ

1
Лучший ответ

Эта:

#include <iostream>
#include <cstdio>

struct log {
    static void logf(std::string, std::string, const char*, ...) __attribute__((format (printf, 3, 4))) {}
};

#define L(m, ...) log::logf("no", __func__, (m), __VA_ARGS__)

int main() {
    //log::logf("hi", "hi", "test %u", "hi");
    L("test %u", "hi");
}

работает отлично, в том смысле, что он дает правильное предупреждение, как показано ниже:

main.cpp: In function 'int main()':
main.cpp:8:61: warning: format '%u' expects argument of type 'unsigned int', but argument 4 has type 'const char*' [-Wformat=]
 #define L(m, ...) log::logf("no", __func__, (m), __VA_ARGS__)
                                                             ^
main.cpp:12:5: note: in expansion of macro 'L'
     L("test %u", "hi");
     ^
At global scope:
cc1plus: warning: unrecognized command line option "-Wno-undefined-internal" [enabled by default]

Итак, я бы предположил, что проблема заключается в параметрах позиции (вы положили 4, 5 в свой атрибут format, когда кажется, что вы должны были поставить 3, 4)....

  • 1
    4, 5 правильно в начальном коде. Обратите внимание, что ваша реализована как статическая функция-член, в то время как оригинал вызвал функцию-член объекта журнала, который добавляет скрытый параметр this . Тем не менее, конструкция работает также с нестатической функцией-членом. @unbekannt: Я могу только предположить, что вам удалось как-то скрыть атрибут формата от вызывающего кода (несколько включаемых файлов, в одном из которых отсутствует атрибут функции format ?).
  • 0
    @mfro, вы абсолютно правы в отношении 4, 5 . Но это все еще работает отлично (давая предупреждение) для меня, смотрите здесь ...
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню