spencer@eecs.umich.edu (Spencer W. Thomas) (07/28/90)
Ok, so I've got this little piece of code that looks like this #include <stdarg.h> int scanargs( argc, argv, format ) int argc; char **argv; char *format; { int retval; va_list argl; va_start( argl, format ); retval = do_scan( argc, argv, format, argl ); va_end( argl ); return retval; } It doesn't work. The first word pointed to by argl is 0. Why? Let's look at the assembly output: scanargs: .option O2 subu $sp, 32 sw $31, 20($sp) % Store frame pointer on the stack sd $4, 32($sp) % Store args 0 & 1 on the stack sw $6, 40($sp) % Store arg 2 on the stack Well, lo and behold, only the first 3 register arguments get put on the stack. The 4th is therefore garbage (on the stack) (but, since scanargs is the first function called in the program, it's 0). But, what's really weird, is that if I use varargs, it does work: #include <varargs.h> int scanargs( va_alist ) va_dcl { int retval; va_list argl; int argc; char **argv; char *format; va_start( argl ); argc = va_arg( argl, int ); argv = va_arg( argl, char ** ); format = va_arg( argl, char * ); retval = _do_scanargs( argc, argv, format, argl ); va_end( argl ); return retval; } scanargs: .option O2 subu $sp, 48 sw $31, 20($sp) % Store frame pointer on stack sd $4, 48($sp) % Store args 0 & 1 on stack sd $6, 56($sp) % Store args 2 & 3 on stack But va_alist is just one argument, running the above through the preprocessor yields: int scanargs( va_alist ) int va_alist; ... I would expect the compiler to only save one register argument on the stack in this case. But it saves all 4! So, what's up? Why does the varargs case work, and the stdarg case not? Is this a compiler botch? Is it an include file botch? Will it be fixed? Should I call the Geometry Hotline? Yours, in confusion, -- =Spencer W. Thomas EECS Dept, U of Michigan, Ann Arbor, MI 48109 spencer@eecs.umich.edu 313-936-2616 (8-6 E[SD]T M-F)
spencer@dip.eecs.umich.edu (Spencer W. Thomas) (07/30/90)
Path: umeecs!zip!spencer From: spencer@eecs.umich.edu (Spencer W. Thomas) Newsgroups: comp.sys.sgi Subject: stdarg.h/code generation botch? Message-ID: <SPENCER.90Jul27162514@spline.eecs.umich.edu> Date: 27 Jul 90 20:25:14 GMT Sender: news@zip.eecs.umich.edu Distribution: comp Organization: University of Michigan EECS Dept Lines: 72 Ok, so I've got this little piece of code that looks like this #include <stdarg.h> int scanargs( argc, argv, format ) int argc; char **argv; char *format; { int retval; va_list argl; va_start( argl, format ); retval = do_scan( argc, argv, format, argl ); va_end( argl ); return retval; } It doesn't work. The first word pointed to by argl is 0. Why? Let's look at the assembly output: scanargs: .option O2 subu $sp, 32 sw $31, 20($sp) % Store frame pointer on the stack sd $4, 32($sp) % Store args 0 & 1 on the stack sw $6, 40($sp) % Store arg 2 on the stack Well, lo and behold, only the first 3 register arguments get put on the stack. The 4th is therefore garbage (on the stack) (but, since scanargs is the first function called in the program, it's 0). But, what's really weird, is that if I use varargs, it does work: #include <varargs.h> int scanargs( va_alist ) va_dcl { int retval; va_list argl; int argc; char **argv; char *format; va_start( argl ); argc = va_arg( argl, int ); argv = va_arg( argl, char ** ); format = va_arg( argl, char * ); retval = _do_scanargs( argc, argv, format, argl ); va_end( argl ); return retval; } scanargs: .option O2 subu $sp, 48 sw $31, 20($sp) % Store frame pointer on stack sd $4, 48($sp) % Store args 0 & 1 on stack sd $6, 56($sp) % Store args 2 & 3 on stack But va_alist is just one argument, running the above through the preprocessor yields: int scanargs( va_alist ) int va_alist; ... I would expect the compiler to only save one register argument on the stack in this case. But it saves all 4! So, what's up? Why does the varargs case work, and the stdarg case not? Is this a compiler botch? Is it an include file botch? Will it be fixed? Should I call the Geometry Hotline? Yours, in confusion, -- =Spencer W. Thomas EECS Dept, U of Michigan, Ann Arbor, MI 48109 spencer@eecs.umich.edu 313-936-2616 (8-6 E[SD]T M-F)
spencer@eecs.umich.edu (Spencer W. Thomas) (07/31/90)
Well, mea culpa. It has been pointed out to me that the correct stdarg usage is: int scanargs( int argc, char **argv, char *format, ... ) very important ^^^ However, I plead a little justified ignorance: I cannot find an on-line man page for stdarg on any of the Iris 4Ds to which I have access. Maybe it's in the printed documenation, but I'm not any where near that. Why did varargs work, you may ask? Well, the compiler recognizes the argument name 'va_alist' as a special case... Anyway, it was 'user error', and I will be more careful to RTFM in the future. -- =Spencer W. Thomas EECS Dept, U of Michigan, Ann Arbor, MI 48109 spencer@eecs.umich.edu 313-936-2616 (8-6 E[SD]T M-F)