Reputation: 1765
I wrote this simple code to find average of numbers using variable arguments -
#include <stdio.h>
#include <stdarg.h>
double avg(int num, ...)
{
va_list arg_list;
double sum=0;
int x;
va_start(arg_list,num);
for(x=0;x<num;x++)
{
double n=va_arg(arg_list,double);
printf("Num = %f\n",n);
sum+=n;
}
va_end(arg_list);
return sum/num;
}
int main(int argc,char *argv[])
{
printf("%f\n",avg(2,2.0,4.0));
return 0;
}
Each of the entered number is converted to double. But if I enter, say, 4 instead of 4.0 in the parameters passed to avg()
in main()
, the compiler cannot seem to type cast it properly. Can anyone point out the mechanism behind this?
Upvotes: 3
Views: 340
Reputation: 5300
When you pass a 4 it is not promoted because the argument is not on the parameter list. The 4 is passed as an int.
Your va_arg
macro will cast the address of the variable on the stack as a pointer to double and dereference it, but the memory there represents an int.
It is basically doing this:
int a = 4 ;
double d = *(double*)&a ;
Not this:
int a = 4 ;
double d = (double)a ;
Upvotes: 3
Reputation: 400049
Of course, the compiler has no idea how you're going to be picking out the arguments in your call to va_arg()
when it compiles the avg()
call.
The types have to match, since for instance int
and double
often have different sizes. Depending on the exact mechanism the compiler uses to pass the arguments, this can lead to mis-matches if you put in a value of one size, and take out one of another. Not good, don't do that.
One way to get this safer is to use printf()
-style specification strings, since many compilers check these so that the arguments match.
Upvotes: 4