Reputation: 33
GCC version ntoarm-gcc (GCC) 4.4.2
I've added 'printf' format attributes to all my functions that wrap printf() and co. They work perfectly fine except when calling the functions using a variadic macro.
class Log { [...]
void log_fmt(LogLevel level, const std::string& funcName, const char_t * const logFormatStr, ...) __attribute__ ((format (printf, 4, 5)));
[...] };
An incorrect direct call like
log.log_fmt(Info, "test", "wrong %u", "type");
yields warning:
format '%u' expects type 'unsigned int', but argument 5 has type 'const char*'
The same incorrect call using a macro yields no warning, however:
#define LOGI(MSG, ...) log.log_fmt(Info, __func__, (MSG), __VA_ARGS__)
LOGI("wrong %u", "type");
Can I get the warnings to show up in this case too? Have I made a mistake or is this intended behaviour?
Upvotes: 1
Views: 3308
Reputation: 8972
This:
#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");
}
works perfectly, in the sense that it gives the correct warning, like below:
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]
So, I would guess that the problem is on the position parameters (you have put 4, 5
on your format
attribute, when it seems that you should have put 3, 4
)....
Upvotes: 2