函数返回值 [英] Return value of function
问题描述
Every function call is executed on the stack and this function is deallocated from the stack memory after the function exits.
Suppose a variable "return_value" is declared as non-static(normal unsigned int) in a function foo(). At the end of the function foo(), this value is returned as
return return_value
This value should have been deallocated from the stack memory. Therefore,how does the main function that is receiving this return value get the correct value returned by foo()?
With one exception, when a function returns a value, that value is returned in one of the machine's registers (or the equivalent). By the time the function is returning, the function's local storage (stack frame) is no longer needed to store the return value; the return value is copied out of a local variable into the return register if necessary.
The exception is functions that return pointers. If a function returns a pointer, and if the pointer value it decides to return points to local (stack frame) data, that's a big problem, because by the time the function has returned, that memory isn't really valid any more, and so the returned pointer value is useless.
Examples:
Function returning a simple constant value:
int f1() {
return 4; /* constant value 4 copied to return register */
}
Function returning value of a local variable:
int f2() {
int i = 5;
return i; /* value copied from i to return register */
}
Function returning a pointer:
int *f3() {
int i = 5;
return &i; /* WRONG: returns pointer to local storage */
}
Function returning a string:
char *f4() {
char str[] = "Hello, world!";
return str; /* WRONG: returns pointer to local storage */
}
A modern compiler will warn you if you try to return a pointer to local storage, as in f3()
or f4()
.
Actually, there's another exception, sort of, when it comes to functions that return structure values. Structures can be arbitrarily large, so a structure return value won't necessarily fit into any of the machine's registers. But the C language definition says that you are allowed to return structure values from functions and have it work properly, so the compiler has to do some extra work for you to make sure that there's some safe place to transport the return value back to the caller.
For example, suppose you write
struct person {
char firstname[100];
char lastname[100];
};
struct person f5() {
struct person ret;
strcpy(ret.firstname, "Akshay");
strcpy(ret.lastname, "Immanuel");
return ret;
}
This might look dangerous (especially if you remember how the earlier example f4()
didn't work), but it turns out it's 100% perfectly okay.
[Footnote. Actually, of course, my example is dangerous in a different way, in that it does not check for overflow when using strcpy
to copy strings into firstname
and lastname
.]
Suppose you call this function from somewhere else:
struct person x;
x = f();
How does this work? Well, it depends on the compiler; different compilers do it different ways. One way is that the compiler essentially pretends that you had written your function differently. It pretends that you had written
void f5(struct person *retp) {
struct person ret;
strcpy(ret.firstname, "Akshay");
strcpy(ret.lastname, "Immanuel");
*retp = ret;
}
And then when you call it, it pretends that you had written
struct person x;
f5(&x);
But the point is that you don't have to write it that way; the compiler does all that for you invisibly, behind your back.
这篇关于函数返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!