Nathan Sidwell <[EMAIL PROTECTED]> writes: > Dave Korn wrote: > >> There was under varargs, which didn't require to pass a named >> argument to va_start; it's only with stdargs that it would be >> impossible. I suspect that this is the underlying reason for the >> code having developed this way: sometimes the first variadic arg is >> the last named arg (stdargs), sometimes it is the first arg _after_ >> the last named arg.
This is exactly backward. See below. > ah, yes, that explains the later comment > /* Handle stdargs. LAST_NAMED is a slight mis-nomer; it's also true > for the unnamed dummy argument following the last named argument. > See ABI silliness wrt strict_argument_naming and NAMED_ARG. So > we only want to do this when we get to the actual last named > argument, which will be the first time LAST_NAMED gets set. */ > I was trying to work out what the 'unnamed dummy argument' was. As we > no longer support varargs, this can be excised. The way you wrote a variadic function definition under the original K+R <varargs.h> was variadic(va_alist) va_dcl { } which would expand to something like variadic(va_alist) int va_alist; { } va_start() would then take the address of va_alist, which was equal to the address of the true first parameter (we are talking VAX-era everything-on-the-stack calling conventions here). So a variadic function, to the compiler, appeared to have one named argument. Now when someone tried to implement <varargs.h> compatibility for GCC, back in the day, they had to do something to put the compiler on notice that this was, in fact, a variadic function being defined here (since they were trying to support more complex calling conventions by then). So what GCC's varargs.h used to do with va_alist and va_dcl was variadic(__va_alist) int __va_alist; ... { } and the ellipsis had roughly the same effect that it did for a variadic function defined to the <stdarg.h> convention. But note the key difference: if this were a stdarg function, "int __va_alist" would be a true, named argument to the function, and the variable, anonymous arguments would start at position 2. It is a varargs function, so "int __va_alist" is a dummy, and the anonymous arguments start at position 1. This is what the comment above refers to. It's inaccurate insofar as the dummy argument does actually have a name, but I don't blame whoever wrote it for getting confused. (I suspect that there was some attempt to support named arguments before va_alist in varargs mode; hence the stuff about the dummy argument coming after named arguments.) It would certainly be nice to get rid of this mess, but Jim Wilson expressed concerns last time it came up: <http://gcc.gnu.org/ml/gcc-patches/2004-01/msg03213.html> zw