use of varargs....portable???

David Lai lai at vedge.UUCP
Fri Apr 8 14:24:34 AEST 1988


Perhaps this has been harped on before, but I seem to have discovered
some interesting differences between 2 C compilers (sun3 and sun4) that
make varargs not so portable.  If you know of any 'portable' varargs
implementations, please let me know.

The sun3 compiler:

	arguments are passed in a linear block of memory (on the stack)
	chars and shorts are widened to int, and narrowed* in the function
	structures are passed on the stack subject to:
		1) If the size of the structure is less than 4
		   then it will be padded on lower addresses
		   and passed as size 4, sizeof in the function
		   will not report the padding
		2) If the structure size is 4 or more, it will
		   be passed unpadded.
	floats are widedened to double, but not narrowed in the function
	everything else passed as is

* narrowed means the sizeof operator reports a the argument's size
  smaller than the argument's real stack usage.  This is important because
  the varargs macro must calculate the real stack usage of the argument.

The sun4 compiler:

	<I'm not sure how arguments are passed, but eventually they
	 appear in a linear block of memory>
	chars and shorts are widened to int, then narrowed
	structures are first copied into some temporary memory, then
	 passed as pointers.  Within the function sizeof shows the
	 actual structure size, not the pointer size.
	floats are widened to double, and not narrowed
	everything else is passed as is

Varargs usage:

	Sun3.  chars and shorts get by using va_arg(ap,int)
	       structures size>=4	     va_arg(ap,struct_type)
	       floats			     va_arg(ap,double)
	       structures size<4:

		declare a fake structure type (it will  be size 4):
			struct fake{ struct struct_type a; short pad;} tmp;
		get the item off the argument list
			tmp = va_arg(ap,struct fake);
		assign the first field to your variable
			str = tmp.a;

	       everything else use its real type  va_arg(ap,type)

	Sun4.  chars, shorts, floats as above
	       structures (nasty)
			str = *(va_arg(ap,struct_type *));
	       everything else		va_arg(ap,type)
-- 
The views expressed are those of the author, and not of Visual Edge or Usenet
David Lai (vedge!lai at oliver.cs.mcgill.edu || ...decvax!musocs!vedge!lai)



More information about the Comp.lang.c mailing list