brahms@spp5.UUCP.UUCP (08/02/86)
The following problem came up while I was trying to compile larn on a pyramid. I'm curious to know if it is a bug with the Pyramid C compiler or something that just happens to work on a number of other machines but not the Pyramid? It appears that the called procedure writes information on what is believes is the top of the stack. Anyway, to get around it, I modifed lprintf from larn to included extra arguments such as in five_int_args below. Script started on Fri Aug 1 15:39:12 1986 demo: cat t.c #include <stdio.h> five_int_args (args, a, b, c, d) int args, a, b, c, d; { int *pargs; int i; pargs = &args; while (*pargs != 0) printf ("%d : ", *pargs++); printf ("%d\n", 0); } show_int_args (args) int args; { int *pargs; int i; pargs = &args; while (*pargs != 0) printf ("%d : ", *pargs++); printf ("%d\n", 0); } main() { show_int_args (0); show_int_args (1, 0); show_int_args (1, 2, 0); show_int_args (1, 2, 3, 0); show_int_args (1, 2, 3, 4, 0); show_int_args (1, 2, 3, 4, 5, 0); five_int_args (1, 2, 3, 4, 0); } demo: cc -o t t.c demo: t 0 1 : 0 1 : 2 : -1072901880 : 320 : 12 : -1072902016 : 0 1 : 2 : -1072901880 : 0 1 : 2 : -1072901880 : 4 : 0 1 : 2 : -1072901880 : 4 : 5 : 0 1 : 2 : 3 : 4 : 0 demo: what /lib/ccom /lib/ccom CCOMP_3.1.9 Mar 19 16:50:26 1986 yaccpar 4.1 (Berkeley) 2/11/83 FLUSH.c 1.2 6/10/81 NEW.c 1.3 6/10/81 UNIT.c 1.2 6/10/81 WRITLN.c 1.2 6/10/81 ERROR.c 1.10 1/10/83 PCEXIT.c 1.1 10/30/80 PCLOSE.c 1.6 1/21/83 PCSTART.c 1.8 1/10/83 PFCLOSE.c 1.3 (Berkeley) 1/21/83 PERROR.c 1.2 1/10/83 PFLUSH.c 1.2 1/21/83 EXCEPT.c 1.3 1/10/83 malloc.c 4.3 (Berkeley) 9/16/83 script done on Fri Aug 1 15:40:23 1986
chris@MIMSY.UMD.EDU.UUCP (08/02/86)
This is not a compiler bug. It is not legal to take the address of one argument and use that to compute the address of another argument. It works on all pure stack machines as long as you know the direction of stack growth. It does not work on mixed stack/register machines like the Pyramid. The proper thing to do in larn's case is to use varargs and vprintf. I am not sure if vprintf is in the `ucb universe' C library, but vprintf(fmt, args) char *fmt; va_list args; { _doprnt(fmt, args, stdout); } should work (since I know how Pyramid did their varargs). Given vprintf, change show_int_args (args) int args; { int *pargs; int i; pargs = &args; while (*pargs != 0) printf ("%d : ", *pargs++); printf ("%d\n", 0); } to #include <varargs.h> show_int_args(va_alist) va_dcl { register int i; va_list p; va_start(p); for (;;) { i = va_arg(p, int); if (i == 0) break; printf("%d : ", i); } printf("0\n"); /* simplified */ va_end(p); } /* emulate a standard printf() */ xprintf(va_alist) va_dcl { char *fmt; va_list p; va_start(p); fmt = va_arg(p, char *); vprintf(fmt, p); va_end(p); } Chris