void demo(int fixed, ...) {
va_list ap;
va_start(ap, fixed); // 1. 定位首個可變參數
int v = va_arg(ap, int); // 2. 按類型取參(每次調用推進)
va_end(ap); // 3. 清理(某些平台必須)
}
typedef char *va_list;
#define va_start(ap, v) (ap = (va_list)&v + __builtin_va_arg_offset(v))
#define va_arg(ap, type) (*(type *)((ap += __builtin_va_arg_size(type)) - __builtin_va_arg_size(type)))
#define va_end(ap) (ap = (va_list)0)
本質:棧幀布局中,固定參數地址已知,可變參數緊隨其後,按類型大小遞增取值。
格式字符串 "%d %s" 在運行期解析,根據格式符調用對應 va_arg(ap, int)/va_arg(ap, char*)。**C 語言本身無類型反射**,所有「智能」皆由程序員編寫解析邏輯實現。
va_arg(ap, int) 實傳 double → 崩潰/亂碼NULL、-1、格式串計數)va_copy(dest, src) (C99) 複製 va_listva_start 需編譯器內建支持void log_msg(const char *fmt, ...) {
va_list ap; va_start(ap, fmt);
vfprintf(stderr, fmt, ap); // vfprintf 內部安全遍歷
va_end(ap);
}