It took me a while to find out, but since C99, C started to support a undefined number of arguments in a function. For this to work stdarg.h header must be included. stdarg.h will introduce a new type, va_list and three functions that operate on objects of this type: va_start, va_arg and va_end. Not only printk uses this, printf for example does too. Let’s stop a bit and study the "magic" ....

Beforehand, the ... must go last in the argument list, without any type, and there must be at least one mandatory, non-optional, first argument. First, we create a pointer to va_list which will point to the first element of the variable argument list. We then need to use va_start(va_list ap, last) macro to initialize our va_list variable. The ap in va_start is our va_list pointer and the second argument (last) is the identifier naming the rightmost parameter (number of arguments) in the parameter list (the one just before the ...). Beware that last argument cannot be defined as a register storage class, function or array. After we have succesfully initialized va_list, we can sequentially access it by using the va_arg(va_list ap, type) macro. When using the va_arg we need to specify the type of the data we are retriving it from. So be careful when doing convertions. After all the argument processing has been done, we need to call va_end(va_list ap) to prevent it from being used any further.

Here is a working snippet:

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

int sum(int nargs, ...){
    va_list ap;
    va_start(ap, nargs);
    int result = 0;

    for (; nargs > 0; nargs--){
            result += va_arg(ap, int);
    }

    va_end(ap);
    return result;
}

int main(int argc, char **argv){
    int value = sum(6, 2, 3, 4, 5, 6, 7);

    printf("Result of sum: %d\n", value);
    return 0;
}