-4

I have learned that this code will print 10, 30, 60 in Terminal.

#include <stdio.h>

void add(int num, ...);

int main(int argc, char const *argv[])
{
    int a=10, b=20, c=30;

    add(1, a);
    add(2, a, b);
    add(3, a, b, c);

    return 0;
}

void add(int num, ...)
{
    int* p = NULL;
    p = &num + 1;

    if (num == 1)
        printf("%d \n", p[0]);
    else if (num == 2)
        printf("%d \n", p[0] + p[1]);
    else
        printf("%d \n", p[0] + p[1] + p[2]);
}

But, it only print odd numbers... :( I just want to print 10, 30, 60 within . Where do you think I should fix?

  • 6
    If you really want to use variadic functions, you should use [`va_arg`](http://en.cppreference.com/w/c/variadic/va_arg) and do it properly. This code you have is terrible. Secondly, you should probably say _specifically_ what you want it to do, and what it actually does, and what you've tried to fix it. But fix the `va_arg` thing first! – Useless Jul 21 '17 at 12:56
  • https://stackoverflow.com/questions/10071186/function-with-unknown-number-of-parameters-in-c – Ilja Everilä Jul 21 '17 at 12:59
  • [as sample code(sum)](https://stackoverflow.com/a/44266152/971127) – BLUEPIXY Jul 21 '17 at 13:01
  • That's so very undefined behaviour … – too honest for this site Jul 21 '17 at 13:20
  • 1
    "I have learned that this code will print 10, 30, 60 in Terminal." - Where did you learn this? You teacher should learn C basics before teaching if he presents such code. That was not valid in the last 28 years **at least**. – too honest for this site Jul 21 '17 at 13:28
  • @HeavyLight Was it your teacher that told you this, or are you reading a web site, or book? – Neil Jul 21 '17 at 13:31
  • @Neil from [this video](https://www.youtube.com/watch?v=ry2g1ck7dN4&index=92&list=PL7mmuO705dG3Z4iSqwzztuPHF3YE8mlbw) at 01:14. – HeavyLight Plum Jul 26 '17 at 23:21

1 Answers1

2

You can't get variadic arguments just by taking the address of the last given parameter and adding to it. How function arguments are laid out on the stack (if a stack is used) is compiler and system dependent. That's why you're getting strange numbers.

The way to do this portably is to use a va_list as follows:

void add(int num, ...)
{
    // the va_list used to retrieve the extra arguments
    va_list args;                  
    int i, sum = 0;

    // use va_start to start processing arguments, passing in the last explicit argument
    va_start(args, num);           
    for (i=0; i<num; i++) {
        // extract the next argument with the given type
        sum += va_arg(args, int);
    }
    // cleanup
    va_end(args);

    printf("%d \n", sum);
}

For more details, see the stdarg man page.

dbush
  • 205,898
  • 23
  • 218
  • 273