我知道如果函数需要将格式字符串传递到 vsnprintf 中,您可以避免出现__attribute__((__format__ (__printf__, 2, 0)))“格式字符串不是字符串文字”的 clang 警告。但是在我的例子中,格式字符串被保存为一个用文字初始化的字段。像这样的东西:
class Worker {
const char* format;
Worker(const char* f): format(f) {...}
void go() {
...
vsnprintf(..,..,format,..);
...
}
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能避免警告?
您可以使用#pragma clang diagnostic ignored "-Wformat-nonliteral"或替换clang为GCC:
#include <cstdio>
#include <cstdarg>
using namespace std;
class Worker {
const char* format;
Worker(const char* f): format(f) { }
void go(int j, ...) {
char data[256];
va_list args;
va_start(args, j);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"
vsnprintf(data, sizeof(data), format, args);
#pragma clang diagnostic pop
va_end(args);
fputs(data, stderr);
}
};
Run Code Online (Sandbox Code Playgroud)
并push限制pop诊断处理中的更改范围,以便只有一行免受警告。有关更多信息,请参阅GNU 诊断编译指示和Clang 诊断编译指示。
上面的代码可以干净地编译:
$ clang -O3 -g -std=c++11 -Wall -Wextra -Werror -Wformat-nonliteral -c clang.cc
Run Code Online (Sandbox Code Playgroud)
它在 GCC 中失败了。替换clang为GCC,它可以在 GCC 和 Clang 下干净地编译。
在 Mac OS X 10.9.2 Mavericks 上测试:
g++)4.8.2clang) 'Apple LLVM 版本 5.1 (clang-503.0.38)(基于 LLVM 3.4svn)'。