va_start and va_end
- C course
- Intermediate
- Lesson 77/116
- 5 min
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.
Practice 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);.
Starter code
#include <stdio.h>
#include <stdarg.h>
// print_numbers: print count ints separated by spaces, end with newline
// declare va_list, init with va_start, read with va_arg in a loop, close with va_end
// main: call print_numbers(3, 10, 20, 30)
int main(void) {
// write here
return 0;
}Sample 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;
}Expected output
10 20 30
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Close the list
va_____(args);
va_end(args);
Explanation: va_end(args) closes the list.
2 What happens if va_arg is used without va_start?
- compile error
- undefined behavior Correct answer
- returns zero
- reads the previous argument
Explanation: Without va_start, va_arg is undefined; usually crashes or reads garbage.
3 va_ tools
| Term | Meaning |
|---|---|
va_list |
type definition |
va_start |
prepare position |
va_arg |
read value |
va_end |
clean up resource |