【问题标题】:GCC: __attribute__ ((format (printf, x, y)) does not seem to work when function is called using a variadic macroGCC:使用可变参数宏调用函数时,__attribute__ ((format (printf, x, y)) 似乎不起作用
【发布时间】:2014-04-09 09:40:39
【问题描述】:

GCC 版本 ntoarm-gcc (GCC) 4.4.2

我已经为包装 printf() 和 co 的所有函数添加了“printf”格式属性。除了使用可变参数宏调用函数时,它们工作得很好。

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");

在这种情况下我也可以显示警告吗?我犯了错误还是这是故意的行为?

【问题讨论】:

  • 宏不检查类型。它们只是重复
  • 你试过-Wall-Wextra参数改成gcc

标签: c++ c gcc macros variadic


【解决方案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]

所以,我猜想问题出在位置参数上(你在 format 属性上放了 4, 5,而你似乎应该放 3, 4)......

【讨论】:

  • 4, 5 在初始代码中是正确的。请注意,您的实现为静态成员函数,而原始调用的日志对象的成员函数添加了隐藏的this 参数。尽管如此,该构造也适用于非静态成员函数。 @unbekannt:我只能假设您设法以某种方式从调用代码中隐藏了格式属性(多个包含文件,其中一个缺少formatfunction 属性?)。
  • @mfro,您对4, 5 的看法完全正确。但它仍然对我完美(发出警告),请参阅here...
  • 受马萨斯回答的启发,我试图在一个最小的例子中让它再次工作。它确实奏效了。它继续在“真实”代码中工作。当这种情况发生时我多么讨厌它......看起来我确实犯了一些愚蠢的错误。接受马萨斯的回答是否可以让我再次尝试?
猜你喜欢
  • 2014-12-31
  • 2013-07-03
  • 1970-01-01
  • 1970-01-01
  • 2012-06-15
  • 2011-01-22
  • 1970-01-01
  • 2014-03-20
  • 2021-07-09
相关资源
最近更新 更多