C
Summary - Variable arguments
Combine va_list and vsnprintf to write a logging function.
Summary - Variable arguments
In this group we learned the four tools of stdarg.h: va_list, va_start, va_arg, va_end. We also wrote printf-like functions with vprintf and vsnprintf.
Mini task: define sum_n and max_n; in main call sum_n(3, 10, 20, 30) and max_n(3, 10, 20, 30) and print both in a single printf. This combines two patterns: accumulation (sum, starts with 0) and seeded comparison (max, starts with the first arg). Each function opens and closes its own va_list; va_end is never skipped. Output: sum 60, max 30.
Exercise Combine sum_n and max_n
Write int sum_n(int count, ...): va_list, va_start(args, count), int total = 0;, for with total += va_arg(args, int), va_end(args), return total. Write int max_n(int count, ...): assign first va_arg to max, for loop reads va_arg, if (v > max) max = v;, va_end, return max. In main call printf("sum %d, max %d\n", sum_n(3, 10, 20, 30), max_n(3, 10, 20, 30));.
Show example solution
#include <stdio.h>
#include <stdarg.h>
int sum_n(int count, ...) {
va_list args;
va_start(args, count);
int total = 0;
for (int i = 0; i < count; i++) total += va_arg(args, int);
va_end(args);
return total;
}
int max_n(int count, ...) {
va_list args;
va_start(args, count);
int max = va_arg(args, int);
for (int i = 1; i < count; i++) {
int v = va_arg(args, int);
if (v > max) max = v;
}
va_end(args);
return max;
}
int main(void) {
printf("sum %d, max %d\n", sum_n(3, 10, 20, 30), max_n(3, 10, 20, 30));
return 0;
}
Care with variable arguments
Variable arguments are powerful but need care. Three key points: no type safety (wrong type to va_arg is undefined), argument count must be known (from count or format string), va_end is never skipped.
If you call va_arg(args, int) and the argument isn't really int, you read garbage; the compiler doesn't check. So printf's format specifiers must match the argument types. Knowing the count is your responsibility; use a count parameter or a NULL terminator (for strings). Safe variants like vsnprintf prevent overflow; always prefer it over vsprintf. These principles underpin robust C libraries.
Test yourself
-
Match the patterns
- sum_n
- starts with 0
- max_n
- starts with first arg
- log_msg
- uses vprintf
- format_into
- uses vsnprintf
-
What must accompany every va_start call?
- two va_arg calls
- a va_end call
- a return statement
- a printf call
Show answer
a va_end call — Every va_start needs a matching va_end.
Next lesson: stdlib.h