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)