Variadic Functions
#include <stdarg.h>
#include <stdio.h>
void varfun(int n,...){
va_list ptr;
int num;
va_start(ptr,n);
num=v开发者_JAVA百科a_arg(ptr,int);
printf("\n%d",num);
}
int main(int argc, char **argv){
varfun(3,7.5,-11.2,0.66);
return 0;
}
Look at the above code, i expect the output to be the first variable parameter value casted to int i.e 7.5 casted to int, i.e. 7. But the output is 0. What is wrong in this?
The va_arg
does not convert the argument. It interprets it as the indicated type. And if the types don't match, you invoke Undefined Behaviour.
va_arg(ptr, int); /* take the next 4 bytes from the stack and interpret them as an `int` */
va_arg(ptr, double); /* take the next 8(?) bytes ... and interpret as double */
(int)va_arg(ptr, double); /* ... convert to int */
Also note the cast isn't really needed in your snippet. The compiler will convert automatically
void varfun(int n, ...) {
va_list ptr;
int num;
va_start(ptr, n);
num = va_arg(ptr, double); /* interpret as double, then convert to int */
printf("%d\n",num);
}
Your second argument, 7.5
is of type double
, but your call va_arg(ptr, int)
is treating it as an int. This means undefined behavior.
A variadic function has to be able to figure out the number and type(s) of the arguments -- and if the caller lies, you're out of luck. printf
-like functions do this via the format string; other functions might treat all their arguments as pointers and use a trailing null pointer as a sentinel.
This is not really casting but merely "reading the first few bytes" (*) of a floating point variable and considering it an integer.
You need to read this argument as its actual type, a double, and then casting as an int.
num = (int) va_arg(ptr, double);
(*) Technically, the behavior associated with va_arg(ptr, wrong_type) is undefined
. "reading the first few bytes" is a figure of speech, only describing what typically may happen. No serious program should rely on such implementation details.
It won't automatically cast the value 7.5 into an int
like that. You'll need to use va_arg
to retrieve the value as a double
and then do the cast afterwards.
va_arg(ptr,int)
is actually expecting the value stored at ptr
to be a bitwise representation of an int
, and it's not.
精彩评论