Pre-DR: va_list objects ======================= C99 7.15#3 says: [#3] The type declared is va_list which is an object type suitable for holding information needed by the macros va_start, va_arg, va_end, and va_copy. If access to the varying arguments is desired, the called function shall declare an object (referred to as ap in this subclause) having type va_list. The object ap may be passed as an argument to another function; if that function invokes the va_arg macro with parameter ap, the value of ap in the calling function is indeterminate and shall be passed to the va_end macro prior to any further reference to ap.214) Does "the called function shall declare an object ... having type va_list" mean that a variable of this type must be declared in the function, or simply that the declarations visible there must permit the construction of a modifiable lvalue expression of type va_list that refers to an object (such lvalue expression being referred to as ap). Do some or all of the following cases have undefined behavior? If so, which? I believe this paragraph should be reworded to avoid placing restrictions on where the object is declared and allocated. Instead, it should be said that the ap parameter is a modifiable lvalue for an object of type va_list, with no further requirements on its declaration or allocation. 1. Object declared outside the function. #include va_list ap; void f (int a, ...) { va_start(ap, a); // ... va_end(ap); } 2. Object declared outside the function but redeclared inside. This would appear to meet the letter of the standard, though there can hardly be any difference to implementations from the previous case. #include va_list ap; void f (int a, ...) { extern va_list ap; va_start(ap, a); // ... va_end(ap); } 3. Pointer to va_list passed in. #include void f (va_list *app, ...) { va_start(*app, app); // ... va_end(*app); } 4. va_list allocated with malloc. #include #include void f (int a, ...) { va_list *app; app = malloc(sizeof(va_list)); if (app) { va_start(*app, a); // ... va_end(*app); } } 5. Array of va_list. #include void f (int a, ...) { va_list apa[10]; va_start(apa[4], a); // ... va_end(apa[4]); } 6. Structure containing va_list. #include void f (int a, ...) { struct { int a; va_list b; } aps; va_start(aps.b, a); // ... va_end(aps.b); }