1. Functions can be written to handle variable number of arguments. For example, printf().

    2. The function prototype should have atleast one known argument followed by ellipsis (set of 3 dots)     which represent any unknown number of arguments passed. The ellispsis should only appear as the last aruments.

 void function(char var1, int var2, ...);

    3. This feature is implemented using a set of macros va_list, va_start, va_arg, va_end, va_copy defined in stdarg.h. All the above macros were defined since C89 except va_copy which is defined since C99.

    4. va_list is a type used to declare a pointer to be used by other macros.

 va_list ap;

    5. va_start is a macro which initializes ap to point to the first anonymous argument (unknown argument) which is stored in stack memory. The known argument just before the ellipsis is used by va_start as a reference in the memory to locate the unknown arguments. va_start should be invoked before va_arg.

 va_start(ap, var2);

    6. va_arg is a macro which retuns an unknown argument on every call and steps ap to the next argument. var_arg uses type name as its second parameter to determine the return type and step size.

 temp = va_arg(ap, );

        The used can be one of the fully promoted types (int, unsigned int, double), its pointer types and void *. The behaviour of va_arg is undefined if the is not compatible with the actual type if there is no next argument.

    7. va_copy is a macro that creates a copy of ap such that the current state of ap is copied.

 va_copy(ap, ap_copy);

    8. va_end clears the ap so that is no more usable. It must be called before returning from the function.

 va_end(ap);

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

int add(int c, ...);

int main()
{
int res1, res2, res3, res4;

res1 = add(3, 1, 2, 3);

res2 = add(5, 1, 2, 3, 4, 5);

res3 = add(7, 1, 2, 3, 4, 5, 6, 7);

res4 = add(9, 1, 2, 3, 4, 5, 6, 7, 8, 9);

printf("res1 = %dnres2 = %dnres3 = %dnres4 = %dn",
res1, res2, res3, res4);
}


int add(int count, ...)
{
int sum = 0, sum2 = 0;
va_list valist, valist2;

va_start(valist, count);

while (count) {
if (count == 2)
va_copy(valist2, valist);

sum += va_arg(valist, int *);

if (count &lt;=2)
sum2 += va_arg(valist2, int);
--count;
}

return sum;
}
 Reference:
    1. K&amp;R – Sec 7.3, Appendix B7
    2. c99 – Sec 4.8

Leave a Reply

Your email address will not be published. Required fields are marked *