2015-11-10 104 views
1

我有一个函数,它接受可变数量的参数,然后根据其他因素将每个参数传递给一个函数。这对于大多数类型的工作良好,而不管它们是否是一个指针va_arg不兼容双工

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 
} 

我知道issuesva_arg和双推广,但我不认为这是我的问题的根源。我把这样的

func(23.4); 

功能正如你所看到的,参数是double文字,所以我不认为我应该与推广方面的问题有关。

为什么va_arg返回一个不正确的值为double s,但不适用于任何其他类型?我是否遇到过某种未定义的行为,并且对double以外的类型感到幸运?

+2

如果'i'“指向”“实例1”的整数,则说明有问题了。该函数需要一个整数,而不是指针。提供一个[mcve]声明你的可变参数函数。作为给予,你不能这样称呼它,因为你缺乏有名的论点。 – Olaf

+1

问题不在于'va_arg'。问题在于你使用'fmtfunc_t'。这违反了6.5.2.2(9)“如果函数被定义的类型与表达式指向的被调用函数指向的类型(表达式)不兼容,**行为是未定义的* *“。 –

+0

@RaymondChen谢谢你,我必须改变我这样做的方式。 (at)Olaf我试着尽可能简短的例子,所以我会添加更多,但我不确定现在是否有必要知道这是未定义的行为。 –

回答

0

的问题,因为在评论中指出的@RaymondChen,@Olaf和@FUZxxl,是通过调用函数与有这样是不符合的声明

char *examp(int i); 

fmtfunt_t func = examp; 
func(va_arg(lst, void *)); //called with an argument of void*, but the parameter is of type int 

我类型参数导致了未定义的行为。我通过获取的参数作为其相应品种

double arg = va_arg(lst, double); 

而不是试图用void *作为一个包罗万象的解决了这个。