user2889159
user2889159

Reputation:

How does work vararg function calling

I'm trying to understand how a variadic function does work. I'm read man stdarg and I'm write the following code:

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

int sum(int count, ...){
    va_list lst;
    va_start(lst, count);
    printf("First=%i,Second=%i,Third=%i, Fourth=%i, Fifth=%i\n",va_arg(lst,int),va_arg(lst,int),va_arg(lst,int),va_arg(lst,int),va_arg(lst,int));
}

int main(){
    sum(1,2,3,4);
}

After compiling and running this i have the following input:

First=0,Second=134513840,Third=4, Fourth=3, Fifth=2.

I don't understand this. I'm expected that First=2, Second=3, Third=4 and Fourth/Fifth has indefined value because after function invocation an arguments pushed to stack from right to left and va_arg(lst, int) just return a pointer to an element which deeper lies in stack.

Upvotes: 4

Views: 551

Answers (2)

Bernd Elkemann
Bernd Elkemann

Reputation: 23560

There are a few small errors (the first one is what i hinted at in my comment):

  • Function-arguments (here of printf()) are evaluated in any order (not necessarily left-to-right) order. You have to add sequence-points to your program by first storing the va_arg-calls in variables or an array.
  • In the first argument you promise to provide the number of args count, but didn't give it.
  • the functions promised to return int.

Like this:

#include <stdarg.h>
#include <stdio.h>
int sum(int count, ...){
    if(count!=5) { printf("this version expects 5 variable args"); return 1; }
    va_list lst;
    va_start(lst, count);
    int a1 = va_arg(lst,int);
    int a2 = va_arg(lst,int);
    int a3 = va_arg(lst,int);
    int a4 = va_arg(lst,int);
    int a5 = va_arg(lst,int);
    va_end(lst); // added for cleanup
    printf("First=%i,Second=%i,Third=%i, Fourth=%i, Fifth=%i\n", 
         a1, a2, a3, a4, a5);
    return 0;
}
int main(){
    sum(5, 1,2,3,4,5);
    return 0;
}
    // prints: First=1,Second=2,Third=3, Fourth=4, Fifth=5

Note that your program expects the number of variable arguments to be 5 but the purpose of var-arg-functions is normally to have the number of arguments be variable, you could write:

#include <stdarg.h>
#include <stdio.h>
int sum(int count, ...){
    va_list lst;
    va_start(lst, count);
    int i=0; for(; i<count; ++i) {
        printf("at %i is %i\n", i, va_arg(lst, int));
    }
    va_end(lst);
    return 0;
}
int main(){
    sum(5, 1,2,3,4,5);
    return 0;
}

Upvotes: 4

Abhishek
Abhishek

Reputation: 2673

This should produce the desired solution.

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

int sum(int count, ...){
    va_list lst;
    va_start(lst, count);
    int first=va_arg(lst,int),second=va_arg(lst,int),third=va_arg(lst,int),fourth=va_arg(lst,int),fifth=va_arg(lst,int);
    printf("First=%i,Second=%i,Third=%i, Fourth=%i, Fifth=%i\n",first,second,third,fourth,fifth);
}

int main(){
    sum(5,1,2,3,4,5);
}

Upvotes: 0

Related Questions