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).