我正在编写的小型 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/