I have a function double max(int count, ...)
in my program. This function should return the highest number, but it reports that -31 > 6
. Where is my mistake? I'm trying to learn va_
. How can I fix this?
double max(int count, ...)
{
double max = INT_MIN, test;
int i;
va_list values;
va_start(values, count);
for (i = 0; i < count; i)
{
test = va_arg(values, double);
if (test > max)
{
max = test;
}
}
va_end(values);
return max;
}
int main()
{
printf("%ld", max(5, 1, 6, -31, 23, 24));
return 0;
}
CodePudding user response:
You are invoking undefined behavior. You are not passing in double
values to max()
, you are passing in int
values instead. int
and double
are different sizes in memory, and va_arg()
can't read an int
parameter as if it were a double
, and vice versa. You need to match the types correctly.
In this example, change all of the double
s to int
s, eg:
int max(int count, ...)
{
int max = INT_MIN, test;
va_list values;
va_start(values, count);
for(int i = 0; i < count; i)
{
test = va_arg(values, int);
if(test > max)
{
max = test;
}
}
va_end(values);
return max;
}
int main()
{
printf("%d", max(5,1,6,-31,23,24));
return 0;
}
Otherwise, change the int
s to double
s instead, eg:
double max(int count, ...)
{
double max = -DBL_MAX, test;
va_list values;
va_start(values, count);
for(int i = 0; i < count; i)
{
test = va_arg(values, double);
if(test > max)
{
max = test;
}
}
va_end(values);
return max;
}
int main()
{
printf("%lf", max(5,1.0,6.0,-31.0,23.0,24.0));
return 0;
}
Either way, you might consider a slight change in logic in how you are handling the max
value. You should initialize it to the 1st value that is passed in, eg:
<type> max(int count, ...)
{
if (count <= 0)
return <default value>;
va_list values;
va_start(values, count);
<type> max = va_arg(values, <type>), test;
for(int i = 1; i < count; i)
{
test = va_arg(values, <type>);
if (test > max)
{
max = test;
}
}
va_end(values);
return max;
}
Also, note that all of the above is the C way of handling things. But you also tagged your question as C , and the C way to handle this would be to use a variadic template instead of ellipses (ie, no va_arg()
needed), or else take a std::initializer_list
or at least a pair of iterator
s so that you can then make use of the standard std::max_element()
algorithm.