c / expert
Snippet
Variadic Argument Delegation and Forwarding via va_list Copying
This snippet illustrates safe two-pass variadic argument processing using stdarg macros in C. The function duplicates the va_list state with va_copy to first measure the formatted output length via vsnprintf(NULL, 0, ...), allocates a buffer of exact size, and then consumes the original va_list to safely render and dispatch the dynamic string.
snippet.c
c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>#include <stdarg.h>#include <stdlib.h>void vformat_and_dispatch(void (*consumer)(const char *), const char *fmt, va_list args) {va_list args_copy;va_copy(args_copy, args);int len = vsnprintf(NULL, 0, fmt, args_copy);va_end(args_copy);if (len < 0) return;char *buf = (char *)malloc((size_t)len + 1);if (!buf) return;vsnprintf(buf, (size_t)len + 1, fmt, args);consumer(buf);free(buf);}void print_consumer(const char *text) {printf("OUTPUT: %s\n", text);}void log_wrapper(const char *fmt, ...) {va_list args;va_start(args, fmt);vformat_and_dispatch(print_consumer, fmt, args);va_end(args);}
Breakdown
1
va_copy(args_copy, args);
Creates an independent clone of the va_list state to allow multiple read passes.
2
int len = vsnprintf(NULL, 0, fmt, args_copy);
Performs a dry-run formatting pass with the cloned va_list to compute required buffer capacity.
3
va_end(args_copy);
Frees memory resources associated with the cloned variadic iterator state.
4
vsnprintf(buf, (size_t)len + 1, fmt, args);
Renders formatted text into the heap buffer using the original argument iterator.
5
va_start(args, fmt);
Initializes the variadic argument iterator starting after the named format string parameter.