tags:

views:

301

answers:

4

Does anyone knows how I might be able to implement variable arity for functions in C?

For example, a summing function:

Sum(1,2,3,4...); (Takes in a variable number of args)

Thanks!

+1  A: 

Have a look at va_arg and friends.

Pavel Minaev
+11  A: 

A variable parameter list of ints. Adjust type as necessary:

#include <stdarg.h>

void myfunc(int firstarg, ...)
{
    va_list v;
    int i = firstarg;

    va_start(v, firstarg);
    while(i != -1)
    {
        // do things
        i = va_arg(v, int);
    }

    va_end(v);
}

You must be able to determine when to stop reading the variable args. This is done with a terminator argument (-1 in my example), or by knowing the expected number of args from some other source (for example, by examining a formatting string as in printf).

Ben M
+1  A: 

If you're trying to implement variable arity functions look at http://www.cprogramming.com/tutorial/lesson17.html for an introduction.

Amuck
+4  A: 

If all aditional arguments are of the same type, you could also pass an array instead of using variadic macros.

With C99 compound literals and some macro magic, this can look quite nice:

#include <stdio.h>

#define sum(...) \
    _sum(sizeof((int []){ __VA_ARGS__ }) / sizeof(int), (int []){ __VA_ARGS__ })

int _sum(size_t count, int values[])
{
    int s = 0;
    while(count--) s += values[count];
    return s;
}

int main(void)
{
    printf("%i", sum(1, 2, 3));
}
Christoph
+1 This is best approach, I use it often. But it will fail if you provide empty argument list. To get around it use following syntax for calculating number of arguments: "sizeof((int[]){0, ##__VA_ARGS__})/sizeof(int)-1". In case of empty list ##__VA_ARGS__ will eat preceding comma.
qrdl
can you elaborate on this? seems abstract to me, thanks :)
nubela
@nubela: see http://stackoverflow.com/questions/1385695/help-me-understand-this-short-chunk-of-code/1386555#1386555
Christoph
@qrdl: you'll also have to modify the second expansion of `__VA_ARGS__`, ie replace `(int []){ __VA_ARGS__ }` with ` most often, I don't bother and accept that it won't work for empty macro invocations...
Christoph
this looks perty ugly... i'd have to go with the accepted answer here too
Claudiu