C
va_start and va_end
Learn the va_start, va_arg and va_end macros.
The va_start and va_end life cycle
va_start and va_end are a pair: a list started with va_start must be closed with va_end. This is required for portability and resource cleanup.
The call va_start(args, count) positions the args list at the argument right after count. After that, each va_arg call reads one argument and advances the position. When all reads are done, va_end(args) is called. On some platforms this does resource cleanup; skipping it leads to undefined behavior. So every function that uses va_start must also use va_end. A simple rule: one va_end for each va_start.
The print_numbers example
You can use va_arg directly inside printf. This prints values without an intermediate variable.
Definition: void print_numbers(int count, ...) { va_list args; va_start(args, count); for (int i = 0; i < count; i++) printf("%d ", va_arg(args, int)); va_end(args); printf("\n"); }. Each loop iteration va_arg(args, int) reads the next integer and printf prints it. After the loop, va_end closes the list, then a newline is printed. The call print_numbers(3, 10, 20, 30) outputs 10 20 30 and a newline. Leaving a space after each number keeps the output tidy.
Exercise The print_numbers function
Write void print_numbers(int count, ...). Start with va_list args; va_start(args, count);. In for (int i = 0; i < count; i++) call printf("%d ", va_arg(args, int));. After the loop va_end(args); and printf("\n");. In main call print_numbers(3, 10, 20, 30);.
Show example solution
#include <stdio.h>
#include <stdarg.h>
void print_numbers(int count, ...) {
va_list args;
va_start(args, count);
for (int i = 0; i < count; i++) {
printf("%d ", va_arg(args, int));
}
va_end(args);
printf("\n");
}
int main(void) {
print_numbers(3, 10, 20, 30);
return 0;
}
Test yourself
-
Close the list
va_____(args);
Show answer
va_end(args);
-
What happens if va_arg is used without va_start?
- compile error
- undefined behavior
- returns zero
- reads the previous argument
Show answer
undefined behavior — Without va_start, va_arg is undefined; usually crashes or reads garbage.
-
va_ tools
- va_list
- type definition
- va_start
- prepare position
- va_arg
- read value
- va_end
- clean up resource
Next lesson: printf-like function