0

I read this page to know how to use variable arguments: https://www.tutorialspoint.com/cprogramming/c_variable_arguments.htm

All right, integer result is ok. But when I replace its type to unsigned char, everything goes wrong:

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

double average(int num,...) {

   va_list valist;
   double sum = 0.0;
   int i;

   /* initialize valist for num number of arguments */
   va_start(valist, num);

   /* access all the arguments assigned to valist */
   for (i = 0; i < num; i++) {
      sum += va_arg(valist, int);
   }

   /* clean memory reserved for valist */
   va_end(valist);

   return sum/num;
}

void foo(unsigned char arg_count,int num,...) {

   va_list valist;
   int i;

   /* initialize valist for num number of arguments */
   va_start(valist, num);

   /* access all the arguments assigned to valist */
   for (i = 0; i < arg_count; i++) {
      printf("%02x,",va_arg(valist, int));
   }

   /* clean memory reserved for valist */
   va_end(valist);
}

void bar(int num,...) {

   va_list valist;
   int i;

   /* initialize valist for num number of arguments */
   va_start(valist, num);

   /* access all the arguments assigned to valist */
   for (i = 0; i < num; i++) {
      printf("%02x,",va_arg(valist, int));
   }

   /* clean memory reserved for valist */
   va_end(valist);
}

int main() {
   printf("Average of 2, 3, 4, 5 = %f\n", average(4, 2,3,4,5));
   printf("Average of 5, 10, 15 = %f\n", average(3, 5,10,15));
   foo(3,'a','b','c');
   printf("\n");
   bar('a','b','c');
}

Result as following:

Compiling the source code....
$gcc main.c -o demo -lm -pthread -lgmp -lreadline 2>&1

Executing the program....
$demo 
Average of 2, 3, 4, 5 = 3.500000
Average of 5, 10, 15 = 10.000000
62,63,400aab,
62,63,00,0a,c0a4700,4009e0,b0ef50a,01,64f5ead8,40000,400934,00,440c7120,400540,64f5ead0,00,00,83cc7120,be487120,00,00,00,bea8d73,be96d10,b6b9950,00,00,00,400540,64f5ead0,40056a,64f5eac8,c0c0180,01,64f5f3d3,00,64f5f3d8,64f5f473,64f5f48d,64f5f4a9,64f5f4b2,64f5f4c8,64f5f4e5,64f5f50d,64f5f796,64f5f7af,64f5f7d9,64f5f7f8,64f5f802,64f5f80a,64f5f823,64f5f83b,64f5f850,64f5f876,64f5f87e,64f5f898,64f5f8d0,64f5f8db,64f5f8e3,64f5f946,64f5f972,64f5f998,64f5fa2d,64f5fa63,64f5fa79,64f5ff2f,64f5ffc9,00,21,64fdb000,10,bfebfbff,06,1000,11,64,03,400040,04,38,05,09,07,be98000,08,00,09,400540,0b,30,0c,30,0d,30,0e,30,17,

Everything was the same with the int version, but why result is different?

10
  • "when I replace its type" What's type? Where? Commented Oct 31, 2017 at 10:02
  • 1
    You seem to have misunderstood. Your comment "initialize valist for num number of arguments" is wrong. Statement va_start(valist, num); only uses num for locating first variable argument, it does not use it's numeric value until it's used in for loop. Commented Oct 31, 2017 at 10:06
  • 1
    That particular tutorial is worded in a misleading way. Find you a different one. In particular, "the one just before the ellipses is always an int" is strongly misleading. It doesn't have to be an int and it doesn't have to represent the total number of variable arguments passed. It hust happens that this particular function chooses to use these conventions. There are nothing in the language that forces them or creates you a varargs count out of thin air. Commented Oct 31, 2017 at 10:32
  • Ok, guys, I know the num isn't the count of variable arguments. But return to the topic, how should I access every arguments? Commented Oct 31, 2017 at 11:28
  • @naive231: I don't understand your question. What is it that you are trying to do? Just print all the arguments? You need some way to tell the varargs function how many arguments you have. Two ways of doing it is by sending the number as the first argument, or by having a special value that marks the end of the argument list. There is no built-in mechanism for getting the number of arguments. Was that the question? Commented Oct 31, 2017 at 14:27

2 Answers 2

3

Replace:

va_start(valist, num);

with

va_start(valist, arg_count);

in foo and change its prototype to:

void foo(unsigned char arg_count, ...) 

You're declaring 3 arguments but starting the va_list 2 from the end.

Also, change this

bar('a','b','c');

to:

bar(3, 'a','b','c');

in main. You have omitted the num argument.

Sign up to request clarification or add additional context in comments.

Comments

3

Maybe I don't understand what it is that you are trying to do with your code, but aren't you just sending 'a', which typically will be the character code 97, as the number of arguments to the function bar? So it tries to print 97 arguments.

va_start(valist, num) initializes valist to start with the argument after num. In both function calls, to foo and bar, 'a' is in the position of num, so the first value from va_arg will be 'b', which is 98 decimal, or 62 hexadecimal.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.