更正"格式字符串不是字符串文字"警告

Nik*_* C. 6 c++ clang

我的代码中有一个警告让我发疯:

int vasprintf_wrapper(char** bufptr, const char* fmt, va_list ap)
{
    // Do stuff...
    // ...
    return vasprintf(bufptr, fmt, ap);
}
Run Code Online (Sandbox Code Playgroud)

Clang(3.6.0),抱怨"格式字符串不是字符串文字",指的fmt是正在转发的参数.

天真地,我试图:

return vasprintf(bufptr, reinterpret_cast<const char[]>(fmt), ap);
Run Code Online (Sandbox Code Playgroud)

哪个当然不编译.

我该怎么办?完全禁用警告不是一种选择.我想要警告.但在这种情况下,我想告诉编译器我知道我在做什么("着名的遗言"旁边的笑话......)

Cor*_*lks 8

启用此类警告的警告标志是-Wformat-nonliteral.由于您不想完全关闭该警告,因此可以使用以下代码在本地禁用此警告:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"

...

#pragma clang diagnostic pop
Run Code Online (Sandbox Code Playgroud)

所以你的功能看起来像这样:

int vasprintf_wrapper(char** bufptr, const char* fmt, va_list ap)
{
    // Do stuff...
    // ...

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"
    return vasprintf(bufptr, fmt, ap);
#pragma clang diagnostic pop
}
Run Code Online (Sandbox Code Playgroud)


The*_*ark 8

您可以使用属性标志告诉Clang您的参数是printf样式格式.请参阅文档

在你的情况下,这样的事情应该工作:

__attribute__((__format__ (__printf__, 2, 0)))
int vasprintf_wrapper(char** bufptr, const char* fmt, va_list ap)
{
  ...
}
Run Code Online (Sandbox Code Playgroud)

编辑:根据Cornstalks的建议将最后一个参数更改为0(关闭检查printf参数).