"Forwarding" 字符串文字

"Forwarding" string literals

我正在处理一个库,它有一个可变参数宏,可以像 printf 一样使用

#define PRINTF_LIKE (FORMAT, ...) //Some statement expression

由于需要 PRINTF_LIKE 来评估某些东西,并且为了避免通常的 if 和悬空 else 具有多个语句的宏的问题,它是使用 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.这意味着我不能写这样的代码:

PRINTF_LIKE("%s", getString().c_str());

其中 getString returns 一个 std::string。为了解决这个问题,我有一个简单的可变参数模板包装器。

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]
}

并像这样使用它:

callPrintfLike("%s", getString().c_str());//warning as shown in the above comment

这触发了 clang 和 gcc 的 -Wformat-nonliteral 警告。有没有办法让我以某种方式"forward" string-literalness 并仅在未使用字符串文字调用 callPrintfLike 时触发此警告?

编辑:下面的答案之一建议使用 __attribute__((format))。但是,that doesn't work 因为 format 属性需要可变函数。

我通过关闭该函数的警告来绕过它,但提供了另一个宏来调用它并通过三元运算符的死分支在此处重新启用这些警告。

//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__))

NEW_PRINTF_LIKE中,printf(FORMAT, ##__VA_ARGS__)永远不会被执行。但是,printf 调用的编译时检查以及有关非文字 FORMAT 和参数与格式字符串不匹配的警告仍将启用。