如何在字段中存储格式字符串并避免格式非文字警告?

时间:2014-03-24 01:48:53

标签: c++ clang printf

我知道如果函数需要将格式字符串传递给vsnprintf,您可以放置​​__attribute__((__format__ (__printf__, 2, 0)))以避免“格式字符串不是字符串文字”的clang警告。但是在我的例子中,格式字符串被保存为一个用文字初始化的字段。像这样:

class Worker {
    const char* format;
    Worker(const char* f): format(f) {...}

    void go() {
        ...
        vsnprintf(..,..,format,..);
        ...
    }
}

如何避免警告?

1 个答案:

答案 0 :(得分:3)

您可以使用#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);
    }
};

pushpop限制了诊断处理中更改的范围,以便只有一行免于警告。有关详情,请参阅GNU diagnostic pragmasClang diagnostic pragmas

上面的代码完全编译:

$ clang -O3 -g -std=c++11 -Wall -Wextra -Werror -Wformat-nonliteral -c clang.cc

GCC失败了。将clang替换为GCC,并在GCC和Clang下完全编译。

在Mac OS X 10.9.2 Mavericks上测试:

  • GCC(g++)4.8.2
  • Clang(clang)'Apple LLVM 5.1版(clang-503.0.38)(基于LLVM 3.4svn)'。