【发布时间】:2014-12-26 23:38:24
【问题描述】:
我知道 C99 中已添加可变参数宏(并通过 GNU 扩展)。我一直想知道在 ANSI C 中是否有一个不错的替代方案。
我想出了这样的东西,但还是有点尴尬:
void log_info(const char *file, int line, const char *fmt, ...)
{
#ifdef DEBUG
va_list ap;
char newfmt[1024] = { 0 };
va_start(ap, fmt);
sprintf(newfmt, "[INFO] (%s:%d): %s\n", file, line, fmt);
vfprintf(stderr, newfmt, ap);
va_end(ap);
#endif
}
这样可以这样调用:
log_info(__FILE__, __LINE__, "info message: %s %d", "helloworld", 12);
这种方法没有错,但是我想知道是否有更好的方法?例如。无需每次都指定文件/行。
如有任何反馈,我将不胜感激。 :)
编辑:这里的 ANSI C 是指 C89。
编辑:下面的答案很好,但我相信鉴于它需要运行打印命令,它可能会带来一些线程安全问题。另一种选择可能是使用定义来最小化打字(也很丑陋):
#define __FL__ __FILE__, __LINE__
然后运行如下命令:
log_info(__FL__, "info message: %s %d", "helloworld", 12);
【问题讨论】:
-
在什么情况下,您可能会使用不支持可变参数宏的编译器编写 C 语言?
-
@Alexis King:感谢您的回复。例如,当 C89 是公司标准或特定项目的要求时?我知道即使使用 -ansi 标志,大多数编译器仍然会编译代码,我的问题不是我为什么要关心,而是如果我受到这样的限制但仍然需要该功能,我会/应该做什么。我必须承认,这更像是一个好奇的问题。
-
请使用
snprintf(newfmt, sizeof(newfmt), "…", …)防止缓冲区溢出。虽然(重新考虑),我想如果你没有 C99,你可能也没有snprintf()。这并不完全正确——MSVC 主要是 C89,但库包括snprintf()。至少,尽可能使用snprintf()。 -
"ANSI C" 用词不当。它通常指的是1989 ANSI C标准所描述的语言(与1990 ISO C标准所描述的语言相同),但实际上ANSI已经采用了ISO C标准的每个版本(1990、1999、2011)出版后不久。
标签: c c89 variadic-macros