http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50581
--- Comment #2 from Wolfgang at Solfrank dot net 2011-10-01 11:06:48 UTC --- (In reply to comment #1) Sorry, I don't quite follow you: > There is no possible valid use of passing arrays to va_arg. What makes you think so? While the 1003.1 definition of va_arg explicitly specifies that the behaviour when passing a type to va_arg that "is not compatible with the type of the actual next argument (as promoted according to the default argument promotions)" is undefined, that doesn't preclude to implement something reasonable, does it? > In C90, it is technically possible to use va_arg in this case without > undefined behavior. The argument passed to the function would have to be > a non-lvalue array - for example, an array in a structure returned from > another function. The result of va_arg would itself be a non-lvalue > array, which it is not possible to convert to a pointer, so it is not > possible to access the values in the array in any way; all that can be > done is to discard the value (call va_arg for its side effects) or to pass > it to another variadic function. Well, I'm not sure that I buy that. But even then, the current implementation in gcc doesn't generate the correct code even only for the side effects. The generated code in fact assumes that the array is passed by value, i.e. the pointer into the argument list (or something equivalent) is incremented by the size of the array instead of the size of a pointer. My main use case for this feature isn't with random arrays, but with va_list itself. On some architectures (AFAIK all architectures that pass some arguments in registers) gcc implements va_list as a one element array of some structure. Without my proposed change, it isn't possible to have a va_list as an argument to a variadic function. This is what my second example in the bug report was about. To show it in a somewhat more real live example, let's assume that vprintf implemented such a feature, something like (using %^ to mean the next two arguments are a format string and a va_list): ------------------------------------------- #include <stdarg.h> int vprintf(char *fmt, va_list ap) { char *fmt1; va_list ap1; while (*fmt) if (*fmt == '%') switch (*++fmt) { case '^': fmt1 = va_arg(ap, char *); va_copy(ap1, va_arg(ap, va_list)); vprintf(fmt1, ap1); va_end(ap1); break; .... } ... } ------------------------------------------- With current gcc, code like this works as expected on processors that implement va_list as a pointer into the parameter list passed on the stack, but doesn't work for processors passing arguments in registers therefor implement va_list as thje above mentioned one element array. Even if I buy your arguments, I consider it a bug that while with -std=c89 the compiler spits an error message, but with -std=c99 it silently generates incorrect code.