问题
I am dealing with a library that has a variadic macro meant to be used like printf
#define PRINTF_LIKE (FORMAT, ...) //Some statement expression
Since PRINTF_LIKE
was required to evaluate to something, and in order avoid the usual if
and dangling else
issue with macros having multiple statements, it was implemented using gcc's statement expressions. However, I need my code to build with the intel compiler, which doesn't allow destructible entities inside a statement expression. This means I can't write code like this:
PRINTF_LIKE("%s", getString().c_str());
where getString
returns an std::string
. To work around this, I have a simple variadic template wrapper.
template <typename ... Rest>
int callPrintfLike(const char* const format, Rest... rest)
{
return PRINTF_LIKE(format, rest...);//warning: format string is not a string literal [-Wformat-nonliteral]
}
And use it like this:
callPrintfLike("%s", getString().c_str());//warning as shown in the above comment
This trips up clang and gcc's -Wformat-nonliteral
warning. Is there a way for me to somehow "forward" string-literalness and have this warning be triggered only when callPrintfLike is not called with a string literal?
EDIT : One of the answers below suggested using __attribute__((format))
. However, that doesn't work since the format
attribute needs a variadic function.
回答1:
I hacked around it by turning warnings off for the function, but providing another macro to call it through and re-enabling those warnings here through a dead-branch of the ternary operator.
//Compiler specific pragmas to turn off the -Wformat-security and -Wformat-literal warnings go here
template <typename ... Rest>
int callPrintfLike(const char* const format, Rest... rest)
{
return PRINTF_LIKE(format, rest...);
}
//Pop diagnostic pragmas
#define NEW_PRINTF_LIKE (FORMAT, ...) (true ? callPrintfLike(FORMAT, ##__VA_ARGS__) : printf(FORMAT, ##__VA_ARGS__))
In NEW_PRINTF_LIKE
, printf(FORMAT, ##__VA_ARGS__)
will never get executed. However, the compile-time checking of the printf
call and warnings about non-literal FORMAT
and arguments not matching the format string will still be enabled.
来源:https://stackoverflow.com/questions/29176591/forwarding-string-literals