【问题标题】:How can I store format string in a field and avoid the format-nonliteral warning as well?如何在字段中存储格式字符串并避免格式非文字警告?
【发布时间】:2014-03-24 01:48:53
【问题描述】:

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

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

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

如何避免警告?

【问题讨论】:

    标签: c++ clang printf


    【解决方案1】:

    您可以使用#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)'。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-07
      • 2012-01-19
      • 2010-12-13
      • 2011-05-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多