Function with variable arguments - strange output

I wrote a small C program that includes variable arguments. See below: -

#include <stdio.h>
#include <stdarg.h>

double calculateAverage(int num,...)
{
  va_list argumentList;
  double sum=0;
  int i;

  va_start(argumentList,num);

  for(i = 0; i < num; i++)
  {
    sum += va_arg(argumentList,double);
  }
  va_end(argumentList);
  return(sum/num);
}

int main()
{
  printf("%f\n",calculateAverage(3,1,2,3));
  printf("%f\n",calculateAverage(4,2,4,6,8));
  printf("%f\n",calculateAverage(4,2.0,4.0,6.0,8.0));
  printf("%f\n",calculateAverage(3,1,2,3));
}

Exit:

0.000000
0.000000
5.000000
5.333333

Only calculateAverage(4,2.0,4.0,6.0,8.0)gives the expected result, i.e. when I specifically represent them with a decimal point.

  • Shouldn't you va_arg(argumentList,double)promote numbers twice safely?

  • How calculateAverage(3,1,2,3)to give 2 results in 2 different places? Am I inside some territory of undefined behavior? If so, how?

I am using gcc version 4.8.1.

+4
source share
3 answers

, . va_arg() , . , 1.0 , 1. 1 double, - .

:

double calculateAverage(int num,...)
{
  va_list argumentList;
  double sum=0;
  int i;

  va_start(argumentList,num);

  printf("%p", &num);
  unsigned char * c =  &num;
  for(i = 0; i < num * sizeof(double) + 4; i++, c++)
  {
    printf(" %02x", *c);
  }
  printf("\n");
   for(i = 0; i < num; i++)
  {
    sum += va_arg(argumentList,double);
  }
  va_end(argumentList);
  return(sum/num);
}

printf("%f\n",calculateAverage(3,1,2,3));

0xbfc507d0 03 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 ...
-0.054776

printf("%f\n",calculateAverage(3,1.0,2.0,3.0));

0xbfd15290 03 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08 40
2.000000

1 00 00 00 01, 1.0 00 00 00 00 00 00 f0 3f ( ).

, 00 00 00 01 00 00 00 02 double, .

+2

sum += va_arg(argumentList,double);

double - Integer literals. int double, .

printf("%f\n",calculateAverage(3,(double)1,(double)2,(double)3));
printf("%f\n",calculateAverage(4,(double)2,(double)4,(double)6,(double)8));
printf("%f\n",calculateAverage(4,2.0,4.0,6.0,8.0));
printf("%f\n",calculateAverage(3,(double)1,(double)2,(double)3));

va_arg , , , .

+2

: , , int (char, short ..), int; float double, int double,

 va_arg(argumentList,double)

, double, . , float, , double.

calculateAverage(4,2.0f,4.0f,6.0f,8.0f);

The solution is to make sure that you pass parameters doubleor use a different type parmN, such as a format string. (Like one of printf)

+2
source

All Articles