dave@UUNET.UU.NET (Speaker-To-Animals) (02/01/89)
I have noticed a change in gcc's stdarg implementation. I'm not sure if it's a bug, but my program no longer works. I first noticed the change with version 1.31 of the compiler, although I believe the change was made in an earlier version. The problem is shown by the following program: #include <stdarg.h> void fred(int, ...); void jim(va_list); void main() { fred(1, 2, 3); } void fred(int i, ...) { va_list ap; va_start(ap, i); jim(ap); printf("FRED %d\n", va_arg(ap, int)); va_end(ap); } void jim(va_list ap) { printf("JIM %d\n", va_arg(ap, int)); } When run with the stdarg.h file supplied with version 1.31 of gcc, the output is: JIM 2 FRED 2 An older version of stdarg.h - sorry, I can't find the original version number - produced: JIM 2 FRED 3 Obviously, the newer version does not `remember' the calls made to va_arg() after the argument pointer has been passed to other functions. The older implementation had definitions like: typedef char *va_list[1]; #define va_start(AP, LASTARG) \ (AP[0] = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) instead of typedef char *va_list; #define va_start(AP, LASTARG) \ (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) My copy of the ANSI standard is a couple of years old. It doesn't make it entirely clear what behaviour is to be expected in a case like this. I see a reference to this change in the ChangeLog file for Feb 1st 1988. Although it is possible to pass the address of the argument pointer, or to return the new value, it seems more convenient to use the old method. Dave Allen Monotype International Science Park Milton Road Cambridge England