简体   繁体   English

va_arg无法使用双打

[英]va_arg not working with doubles

I have a function that takes a variable number of arguments, and then passes each argument to a function, depending on other factors. 我有一个函数,它接受可变数量的参数,然后根据其他因素将每个参数传递给函数。 This is working well for most types, regardless of whether or not they are a pointer 这对于大多数类型都适用,无论它们是否是指针

func = (fmtfunc_t)dictobj(deflt, tok);
dat = func(va_arg(lst, void *));

where fmtfunc_t is defined as 其中fmtfunc_t被定义为

typedef char * (*fmtfunc_t)(void *);

This method works, for example, with functions like the following 例如,此方法适用于以下功能

char *examp1(int i) {
    // i points to the correct integer value
}
char *examp2(char *s) {
    // s points to the correct string value
}

However, it does not work when the argument is a double 但是,当参数为double时,它将不起作用

char *examp3(double d) {
    // d is 0
}

I am aware of issues with va_arg and double promotion, but I don't believe that this is the root of my problem. 我知道va_arg和双重晋升的问题 ,但是我不认为这是我问题的根源。 I call the function like this 我这样调用函数

func(23.4);

As you can see, the argument is a double literal, so I don't believe I should be concerned with promotion issues. 如您所见,该参数是double字面量,因此我不认为我应该关注晋升问题。

Why is va_arg returning an incorrect value for double s, but not for any other type? 为什么va_argdouble s返回错误的值,但对于其他任何类型都不返回错误的值? Am I encountering some kind of undefined behavior and getting lucky with types other than double ? 我是否遇到某种未定义的行为,并且对double以外的类型感到幸运?

The issue, as pointed out by @RaymondChen, @Olaf, and @FUZxxl in the comments, was that, by calling the functions with arguments that had types that were incompatible with the declarations @ 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

I was causing undefined behavior. 我正在引起不确定的行为。 I solved this by fetching the arguments as their appropriate types 我通过将参数作为适当的类型来解决了这个问题

double arg = va_arg(lst, double);

Rather than trying to use void * as a catch-all. 而不是尝试使用void *作为包罗万象的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM