【发布时间】:2015-11-10 20:11:11
【问题描述】:
我有一个函数,它接受可变数量的参数,然后根据其他因素将每个参数传递给一个函数。这适用于大多数类型,无论它们是否是指针
func = (fmtfunc_t)dictobj(deflt, tok);
dat = func(va_arg(lst, void *));
fmtfunc_t 定义为
typedef char * (*fmtfunc_t)(void *);
此方法适用于例如以下功能
char *examp1(int i) {
// i points to the correct integer value
}
char *examp2(char *s) {
// s points to the correct string value
}
但是,当参数是 double 时,它不起作用
char *examp3(double d) {
// d is 0
}
我知道issues 与va_arg 和双重提升,但我不相信这是我问题的根源。我这样调用函数
func(23.4);
如您所见,参数是 double 文字,所以我认为我不应该关心促销问题。
为什么va_arg 为doubles 返回一个不正确的值,但没有为任何其他类型返回?我是否遇到了某种未定义的行为,并且对double 以外的类型感到幸运?
【问题讨论】:
-
如果
i“指向”examp1的整数,那么已经有问题了。该函数需要一个整数,而不是指针。提供带有可变参数函数声明的minimal reproducible example。作为给定,你不能这样称呼它,因为你缺少一个命名参数。 -
问题不在于
va_arg。问题在于您使用fmtfunc_t。这违反了 6.5.2.2(9) “如果函数定义的类型与表示被调用函数的表达式所指向的(表达式的)类型不兼容,行为未定义。” -
@RaymondChen 谢谢你,我将不得不改变我这样做的方式。 (at)Olaf 我试图使示例尽可能简短,所以我会添加更多,但我不确定现在是否有必要,因为我知道这是未定义的行为。
-
其实再看一遍,问题也在
va_arg。 7.15.1.1(2):“如果 type 与实际下一个参数的类型不兼容(根据默认参数提升),行为未定义 ,但以下情况除外[均不适用]。”我猜你看到问题的原因只是double是int和void*以相同的方式传递(在 GP 寄存器中),但double在 FP 寄存器中传递。 -
你正在尝试做的事情是行不通的。您不能简单地获取任何类型的参数并期望它起作用。
标签: c variadic-functions