“Forwarding” string literals

穿精又带淫゛_ 提交于 2020-01-04 05:06:06

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!