Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!henry From: henry@utzoo.UUCP (Henry Spencer) Newsgroups: comp.lang.c Subject: Re: structure function returns -- how? Message-ID: <7434@utzoo.UUCP> Date: Fri, 19-Dec-86 14:09:06 EST Article-I.D.: utzoo.7434 Posted: Fri Dec 19 14:09:06 1986 Date-Received: Fri, 19-Dec-86 14:09:06 EST References: <131@hcx1.UUCP> <773@maynard.BSW.COM> <7403@utzoo.UUCP>, <490@aw.sei.cmu.edu.sei.cmu.edu> Organization: U of Toronto Zoology Lines: 63 > (c) Function allocates static space and returns pointer. Caller copies. > > This is not reentrant, as has been pointed out. Nor does it work if > the function is recursive... Not true, given proper code generation. The static area need be in use only during the return sequence, hence recursion is no problem -- execution of multiple instances of a recursive function overlaps, but the return sequences need not. Static-area return values may even speed up recursive returns, since less copying may be needed. Reentrancy is another story, although it should be noted that reentrancy is another story for a *whole* *lot* of things in a C/Unix environment: a signal handler has to be very careful, since locking out signal handlers during critical sections in (say) stdio is expensive and hence seldom done. >(e) Function leaves result on stack. > > This is usually easiest for the function. The problem is that on many > systems an interrupt or signal will destroy the result. (flame)(This is a > symptom of a major and persistent system design error: the use of a > hardware register pointing into user space as a place to dump junk. It > is compounded by language implementations that use the hardware stack > to allocate the LIFO address space of local variables)... No, it's a symptom of a major and persistent software error: using a stack pointer as if it were an index register. If you get it firmly into your head that you are dealing with a *stack*, not just an index register that happens to increment and decrement automatically in some circumstances, then the problem goes away. When you say "leaves result on stack", what you really mean is "leaves result beyond the end of the stack, assuming that the stack will not be used as a stack until the result is picked up". It is possible, although often awkward, to leave the result *on the stack*, i.e. as if it had been pushed onto the stack, in which case there isn't a problem with interrupts or signals. (This is approximately what your e3 alternative does, but in an unnecessarily roundabout way using a magic run-time routine.) > (d) Function allocates heap space, rest as above. > > ...always works but can be rather expensive. It always works in the absence of reentrancy, or if your memory allocator is reentrant, which many aren't. Additional alternatives that you have missed are some variations on (b) (caller preallocates): (1) it isn't necessary for the address to be passed as a parameter if the caller and callee can establish mutual agreement on where the result goes, although this is generally practical only if the stack is contiguous; (2) it may be possible to use the argument area as the return area, if the caller ensures it is big enough and avoids popping it off the stack or re-using it before picking up the result, and the callee makes sure that result copying comes after all uses of arguments (especially in the case where the returned value is the value of an argument). [Incidentally, it reflects badly on you to chide us for re-inventing the wheel when you seem not to be aware of some of the prior art yourself. You might find Bell Labs Computing Science Tech Report No. 102, "The C Language Calling Sequence", by Johnson and Ritchie, Sept. 1981, to be interesting reading.] -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,decvax,pyramid}!utzoo!henry