函数返回值 [英] Return value of function

查看:25
本文介绍了函数返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆