richw@rosevax.Rosemount.COM (Rich Wagenknecht) (11/11/87)
I have two questions: 1) What happens in C when a function returns a value which the calling line does not assign to a variable? Where does this value end up? (example: strcpy(str1,str2); ) Could someone explain the process that is gone through when a function is called? 2) Specific to IBM Pc compilers. I am trying to write some disk routines (using DOS interrupts <-sp?) I am not sure which memory model I will need for a large application program I will soon write. How can I generalize these routines to work with any memory model. I am specifically concerned with pointers (near/far). Thankyou in advance. Rich Wagenknecht
firth@sei.cmu.edu (Robert Firth) (11/12/87)
In article <3094@rosevax.Rosemount.COM> richw@rosevax.Rosemount.COM (Rich Wagenknecht) writes: > 1) What happens in C when a function returns a value which the > calling line does not assign to a variable? Where does this > value end up? (example: strcpy(str1,str2); ) Could someone > explain the process that is gone through when a function is > called? Can't answer the other question, but this one maybe I can help. If the function returns a "small" value, such as an int, then its last action before returning is normally to compute the result and leave it in a specific register (eg R0). The caller then expects to find it there. So, for instance x = f() will compile as call f store result from R0 (or wherever) into x If you simply call the function thus f() then the result still comes back in R0 but isn't used. So it is destroyed when the code next decides to use R0. The case of a "large" value is different. The proper way to implement this is for the caller to create a temporary and pass a pointer to it. So, given bigf() returning a large value (of a type T, say) x = bigf() compiles into { T temp bigf (&temp) x = temp } which can sometimes be optimised to just bigf(&x). The function of course copies the return value into the thing pointed at by its (hidden) first parameter. If you now just call bigf(), then the compiler still must generate a temporary and actually emit bigf(&temp), otherwise the poor function will write its result through an undefined pointer. C implementors being what they are, I won't assert that all compilers get this right. Finally, an older way of implementing things like bigf() had the function store its result in a static temporary. This is plain wrong, so I won't discuss it further.
carroll@snail.UUCP (11/13/87)
In most compilers, a certain register on the processor is used to hold return values. When it is assigned, it is moved out of the register and into the appropriate variable, or tested (as in if(open(...) < 0)). If it is not used, then the value in the register is just overwritten next time it's used. On '86 CPU's, it's usually ax, on most PDP style machines it's r0.
ftw@datacube.UUCP (11/14/87)
richw@rosevax.UUCP writes: > I have two questions: > 1) What happens in C when a function returns a value which the > calling line does not assign to a variable? Where does this > value end up? (example: strcpy(str1,str2); ) Could someone > explain the process that is gone through when a function is > called? Usually, a function return value gets stuck in a spare register. The compiler vendor will will have a standard mechanisim for passing back return values for functions. For instance, most 68K C compilers that I have come across will stick function returns in register d0; Whitesmiths uses d7, etc. Aggregates are more complicated. If the caller does not use the return value, it will remain where it was put until overwritten by something else. In a stack based machine, when a function is called, all the args to that function are pushed on the stack in some agreed-upon order, along with the return address. The called function accesses its arguments by using offsets from the current value of the stack pointer. The stack is unwound when the called function returns. > 2) Specific to IBM Pc compilers. I am trying to write some > disk routines (using DOS interrupts <-sp?) I am not sure which > memory model I will need for a large application program I will > soon write. How can I generalize these routines to work with any > memory model. I am specifically concerned with pointers (near/far). Someone else will have to take this one. I do get the impression that such a thing would be at least rather tricky. > Thankyou in advance. > Rich Wagenknecht Farrell T. Woods Datacube Inc. Systems / Software Group 4 Dearborn Rd. Peabody, Ma 01960 VOICE: 617-535-6644; FAX: (617) 535-5643; TWX: (710) 347-0125 INTERNET: ftw@datacube.COM UUCP: {rutgers, ihnp4, mirror}!datacube!ftw
gwyn@brl-smoke.ARPA (Doug Gwyn ) (11/14/87)
In article <3094@rosevax.Rosemount.COM> richw@rosevax.Rosemount.COM (Rich Wagenknecht) writes: > 1) What happens in C when a function returns a value which the > calling line does not assign to a variable? Where does this > value end up? (example: strcpy(str1,str2); ) Could someone > explain the process that is gone through when a function is > called? Just as with the value of "x = 1", the value of the expression is used only if the programmer chooses to use it. It is misleading to ask where the value ends up; it is up to the compiler to do the right thing (which amounts to not having the value "end up" anywhere that it was not explicitly placed by the programmer). The process that occurs when a function-call expression is evaluated at run time is: 1. The arguments are evaluated (in unspecified order). 2. The formal parameter variables in the function definition receive the corresponding values of the arguments. 3. The body of the function definition is evaluated until an explicit "return" expression is evaluated or the end of the body is reached (which constitutes an implicit "return;"). 4. If the function returns a value and its evaluation ended with a "return" that had a value as its operand, that value replaces the function invocation in the calling context, and that higher-level evaluation process resumes using that value. (If the value is not explicitly used by the programmer, then evaluation simply proceeds to the next expression.) This is really no different from most programming languages that support functions, although C is unusual in that all arguments are passed by value (array names are apparent exceptions; by the funny C rules for array names in various contexts, they are converted to pointers to the first members of the arrays when passed as arguments, which is similar to "call by reference" found in some languages).