va_list has some disadvantages associated with the uncertainty of function arguments:
- when calling such a function, the compiler does not know what types of arguments are expected, so the standard imposes some "normal conversions" before the arguments are passed to the function. integers narrower than
int , all float are promoted to double . In some borderline case, you have not received what you require in the called function. - In the called function, you tell the compiler what type of argument you expect and how many of them. There is no guarantee that the caller will receive this right.
If you pass the number of arguments anyway, and they have the same known type, you can just pass them with a temporary array written for C99:
void add_vertices(graph G, vertex v, size_t n, vertex neigh[n]);
would you call it something like this
add_vertices(G, v, nv, (vertex []){ 3, 5, 6, 7 });
If this calling convention looks too ugly for you, you can wrap it with a macro
#define ADD_VERTICES(G, V, NV, ... ) add_vertices((G), (V), (NV), (vertex [NV]){ __VA_ARG__ }) ADD_VERTICES(G, v, nv, 3, 5, 6, 7);
here ... indicates a similar concept for macros. But the result is much safer, since the compiler can perform type checking, and this is not delayed.