【发布时间】:2012-09-12 12:51:58
【问题描述】:
我创建了一个类似printf 的函数,它接受以下参数:
- 一个强制参数(自定义错误代码)
- 可选格式字符串
- 格式参数的可变计数
函数原型如下:
int my_printf(int err_code, ...);
err_code 还包括是否给出格式字符串(和可能的格式标签)的信息。
如果给定它们,我可以使用va_arg 函数提取格式字符串并将其与其余参数一起传递给vfprintf。
调用看起来像:
my_printf(-ERR_SIMPLE);
my_printf(-ERR_COMPLICATED, "Error: problem with %d", 123);
很遗憾,我无法使用 GCC 属性进行格式类型检查,因为它需要 string-index:
格式(原型、字符串索引、首先检查)
仍然可以进行类型检查吗? 使用辅助宏、辅助函数、修改可选格式字符串部分等的解决方案是可以接受的。
更新:
我不确定是否可以将修改后的va_list 传递给vfprintf 类函数。见 cmets。
如果可能的话,最好避免这种情况,并为可选的格式字符串部分使用宏或其他东西。
【问题讨论】:
-
你的函数到底是如何工作的?如何从 valist 中去除格式字符串参数?
-
@KerrekSB 我用 const char *fmt = va_arg(args, const char *); 得到格式字符串。然后我可以简单地调用 vfprintf(stdout, fmt, args);
-
那不是UB吗?我敢肯定,如果您已经开始胡思乱想,您将无法将 valist 传递给函数...
-
@KerrekSB 我不确定。它似乎适用于 x86 上的 GCC 4.4.5。我想我应该避免这种情况。但是,该问题仍然有效(并且已更新)。
-
好吧,如果我们已经在该领域或可怕的黑客攻击,我不会太担心获得正确的属性:-)