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");
产生警告:
格式“%u”需要类型“unsigned int”,但参数 5 的类型为“const char*”
但是,使用宏的相同错误调用不会产生任何警告:
#define LOGI(MSG, ...) log.log_fmt(Info, __func__, (MSG), __VA_ARGS__)
LOGI("wrong %u", "type");
我也可以在这种情况下显示警告吗?我是否犯了错误或者这是有意为之的行为?
最佳答案
这个:
#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
)...
关于c++ - GCC:__attribute__ ((format (printf, x, y)) 在使用可变参数宏调用函数时似乎不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22958570/