return(struct) implementation

Karl Heuer karl at haddock.ima.isc.com
Wed Mar 8 07:33:24 AEST 1989


In article <4425 at pt.cs.cmu.edu> marcoz at MARCOZ.BOLTZ.CS.CMU.EDU (Marco Zagha) writes:
>Can anybody explain how returning a structure from a function is
>typically implemented.  Assume it is too big to use registers.

Some broken implementations use a static area in the callee and just return
its address.  This mechanism is not reentrant, is forbidden by the pANS, and
will be considered no further in this article.

Generally, the caller finds space for the object, and ensures that the callee
knows the location of this space.  (Small structs are a special case of this,
where the caller finds space in the registers, and the callee already knows
the location, since it's constant.  Note that `location' does not mean
`address' in this example.)  Usually the second part of this protocol is
handled by having the caller pass the address of the struct as a `hidden
argument'; this can be done either using the normal argument-passing scheme
(so that f(x) generates code that looks like f(&hidden, x)) or any other
consistent strategy (some compilers have the caller put the address in a known
register, which is not otherwise used in argument passing).

The first part of the protocol can be achieved, if necessary, by reserving
enough stack space ahead of time, and passing &hidden as if `hidden' were an
auto variable.  However, since the usual thing to do with a struct-returning
function is to store its return value in a struct, the expression `y=f(x)',
which would normally generate code resembling `f(&hidden, x); y=x', can often
be optimized to `f(&y, x)'.  I leave it as an exercise for the student to
determine the conditions under which this optimization is legal.

>[If it's on the stack,] where does the return structure go in relation to
>parameters to the function?

It's normal for the arguments to be the last things pushed on the stack, so
that they can be cleaned up easily.  Thus the space for the return value
itself ought to be upward of the args, if the stack grows downward.

>Since I suspect this is implementation dependent, please specify
>what implementation you are describing.

Most of what I've said is pretty generic; read `vax' for a concrete example.
I believe it was the 3b20 that used the special register.

Btw, the program
	typedef struct { char junk[8192]; } foo;
	static foo dummy;
	foo f() { return dummy; }
	main() { (void)f(); }
can be used to test for a certain compiler bug.

Karl W. Z. Heuer (ima!haddock!karl or karl at haddock.isc.com), The Walking Lint



More information about the Comp.lang.c mailing list