c - 避免在 printf 周围的包装器中发出警告

标签 c string compiler-warnings string-literals

我正在编写的小型 C 库中有一个错误报告功能。除了普通的 error 函数之外,我还想提供一个 errorf 函数,以便轻松地将信息嵌入到错误消息中。

/*
 * Prints a formatted error message. Use it as you would use 'printf'. See the
 * 'sio_error' function.
 */
void sio_errorf(const char *format, ...) {
    // Print the error prefix                           
    if (g_input == STDIN) fputs("error: ", stderr);
    else fprintf(stderr, "%s: ", g_progname);

    // Pass on the varargs on to 'vfprintf'. 
    va_list arglist;
    va_start(arglist, format);
    // This may produce the following warning -- ignore it:
    //     warning: format string is not a string literal
    vfprintf(stderr, format, arglist);
    va_end(arglist);
    fputc('\n', stderr);
}

问题是,我收到此警告(使用带有 -Weverything 开关的 clang 4.0 进行编译):

warning: format string is not a string literal

我明白为什么这样做会很糟糕。有什么办法可以摆脱这个警告吗?我能否以某种方式强制 format 参数 sio_errorf 是一个字符串文字,以便编译器知道它始终是,而我只是将它传递下去?

我知道我可以使用 -Wno-format-nonliteral,但前提是其他人也打算手动编译它,他们不会那样做。我宁愿源代码中有一些东西可以消除警告。

理想情况下,如果我传递给 sio_errorf actually 的字符串不是文字,我仍然会收到警告,但我不确定这是否可能。

最佳答案

如果您使用的是 GCC 或其亲戚之一,请在声明中尝试一个属性:

void sio_errorf(const char *format, ...) __attribute__((format(printf, 1, 2)));

要将属性添加到定义中,您可以使用:

__attribute__((format(printf, 1, 2)))
    static void sio_errorf(const char *format, ...) {
      ....

关于c - 避免在 printf 周围的包装器中发出警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12171132/

相关文章:

c++ - 找到一个 m*m (2<=m<n) 且总和最大的子数组;从 n*n int 数组中(有 +ve、-ve、0)

将 C 中的迭代算法更改为递归

java - 在 JUnit 测试中抑制编译器警告

c++ - 没有警告的返回语句后的代码

c# - 在 .NET 中换行

c++ - 确保在 C++ 编译时正确的双指针传递方法

c - 重复图像检测算法?

c - c 如何允许不传递所有参数?

regex - 删除R中两种字符串模式之间的字母

sql - 如何在 PostgreSQL 字符串中的单引号后添加分号?