[comp.lang.c] Functions returning structures

jimm@amc-gw.amc.com (Jim McElroy) (06/01/90)

I do embedded system programming in C using Intel type
processors and have used the Microsoft compilers for the most
part.  This is a question for those who have information
regarding the implementation of functions that return
structures.

The Microsoft 5.1 compiler implements functions that return
structure values by storing the return value in a statically
allocated buffer that is declared by the called function.  The
code that calls the function actually gets a return value that
is a pointer to this static buffer.  The caller can then copy
the value, select a member, ignore it or anything else.

After thinking about this a little while, I realized that this
works fine in _almost_ all cases; all the usual calls in which
the return value is used work fine; the function can even call
itself recursively and use the value returned as part of a
computation to generate a new value to return and so forth.  The
only place this gets in trouble is in a multi-tasking situation
in which the time slice of one task (or thread) gets pre-empted
while that static buffer is either being filled (by the called
function) or being used (by the code that did the call).

Now, lets say, a different execution thread calls the
unfortunate function.  This will trash the value in the static
buffer and _very strange things_ will of course happen.  So we
can say that the function may be called recursively, but is not
re-entrant in the general case.

Now, the questions are these:

    Does the Microsoft version 6.0 compiler do this better or
    differently? (After all, they support multiple threads under
    OS2.)

    If not, is there another MS-DOS compiler that does it the
    "right" way?  ("Right" for us multi-thread :-) guys.)

The "right" way would have to be some method of keeping all
relevant data on the stack (or dynamically allocated elsewhere).
The method that comes to mind is for the calling code, knowing
that is is calling a function that returns a structure, to
allocate the return value buffer on the stack in a standard way
so that it can be found by the called function.  Doing this,
however, would result in a mess if a structure valued function
was called by a program that did not expect the structure
return.  The called function would write all over important
values on the stack!  You would have to use the correct prototype
even if you intended to ignore the return value.

Any info appreciated.

Jim McElroy

jordan@aerospace.aero.org (Larry M. Jordan) (06/01/90)

I have been a very satisfied user of JPI's Modula-2, which supports
the returning of any structured type as a function result in the
presence of multiple threads of execution (this is after all one of
reasons Wirth created Modula).  JPI also offers an ANSI C compiler
which apparently borrows much from its Modula-2 brother.  I would
look to JPI's TopSpeed C.  They seem to do most things right.
(No, I do not work for or own stock in JPI).