wkd@asc.slb.com (06/22/89)
Using gcc-1.35, on SUN4 and SUN3, running SunOs4.0.1. The following program crashes because 'stdarg.h' only works for arguments that are 'int' or whose size is a multiple of sizeof(int). ======================== test.c ================================ #include <stdarg.h> void foo(int a, char b, ...) { va_list ap; char *p; va_start(ap, b); p = va_arg(ap, char *); printf(p); } main() { foo(1, 'c', "hello world\n"); } ========================= end ================================== Here is a new stdarg.h that works correctly: ========================== stdarg.h ============================ #ifndef _STDARG_H #define _STDARG_H typedef char *va_list; /* Amount of space required in an argument list for an arg of type TYPE. TYPE may alternatively be an expression whose type is used. */ #define __va_rounded_size(TYPE) \ (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) #if !defined(sparc) && !defined(__sparc__) #define va_start(AP, LASTARG) \ (AP = ((char *) &(LASTARG) + sizeof(LASTARG))) #else #define va_start(AP, LASTARG) \ (__builtin_saveregs (), \ AP = ((char *) &(LASTARG) + sizeof(LASTARG))) #endif void va_end (va_list); /* Defined in gnulib */ #define va_end(AP) #define va_arg(AP, TYPE) \ (AP += __va_rounded_size (TYPE), \ *((TYPE *) (AP - sizeof(TYPE)))) #endif /* _STDARG_H */ =================================== end ===================================== Here are the diffs: sake[wkd](71)% diff -btwc stdarg.h $GNU/gcc-1.35/sun4 *** stdarg.h Thu Jun 22 09:14:18 1989 --- /nfs/hamachi/local/gnu/gcc-1.35/sun4/stdarg.h Tue May 16 08:24:13 1989 *************** *** 11,21 **** #if !defined(sparc) && !defined(__sparc__) #define va_start(AP, LASTARG) \ ! (AP = ((char *) &(LASTARG) + sizeof(LASTARG))) #else #define va_start(AP, LASTARG) \ (__builtin_saveregs (), \ ! AP = ((char *) &(LASTARG) + sizeof(LASTARG))) #endif void va_end (va_list); /* Defined in gnulib */ --- 11,21 ---- #if !defined(sparc) && !defined(__sparc__) #define va_start(AP, LASTARG) \ ! (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) #else #define va_start(AP, LASTARG) \ (__builtin_saveregs (), \ ! AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) #endif void va_end (va_list); /* Defined in gnulib */ *************** *** 23,28 **** #define va_arg(AP, TYPE) \ (AP += __va_rounded_size (TYPE), \ ! *((TYPE *) (AP - sizeof(TYPE)))) #endif /* _STDARG_H */ --- 23,28 ---- #define va_arg(AP, TYPE) \ (AP += __va_rounded_size (TYPE), \ ! *((TYPE *) (AP - __va_rounded_size (TYPE)))) #endif /* _STDARG_H */ sake[wkd](72)% Bill Duttweiler (wkd@ASC.SLB.COM)