首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >函数返回值

函数返回值
EN

Stack Overflow用户
提问于 2016-01-30 10:11:43
回答 2查看 3.6K关注 0票数 3

每个函数调用都在堆栈上执行,该函数在函数退出后从堆栈内存中释放。

假设在函数foo()中,变量"return_value“声明为非静态(普通无符号int)。在函数foo()的末尾,此值作为

代码语言:javascript
复制
return return_value

应该从堆栈内存中释放此值。因此,接收此返回值的主函数如何获得foo()返回的正确值?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-30 10:20:20

除了一个例外,当一个函数返回一个值时,该值将在机器的一个寄存器(或等效的)中返回。函数返回时,不再需要函数的本地存储(堆栈帧)来存储返回值;如果有必要,返回值将从局部变量复制到返回寄存器中。

例外情况是返回指针的函数。如果函数返回指针,如果指针值决定将点返回到本地(堆栈帧)数据,这是一个大问题,因为当函数返回时,该内存不再有效,因此返回的指针值是无用的。

示例:

函数返回一个简单的常量值:

代码语言:javascript
复制
int f1() {
    return 4;        /* constant value 4 copied to return register */
}

函数返回局部变量的值:

代码语言:javascript
复制
int f2() {
    int i = 5;
    return i;        /* value copied from i to return register */
}

函数返回指针:

代码语言:javascript
复制
int *f3() {
    int i = 5;
    return &i;       /* WRONG: returns pointer to local storage */
}

函数返回字符串:

代码语言:javascript
复制
char *f4() {
    char str[] = "Hello, world!";
    return str;      /* WRONG: returns pointer to local storage */
}

如果试图返回指向本地存储的指针(如f3()f4()中的指针),现代编译器将警告您。

实际上,当涉及返回结构值的函数时,还有另一个例外。结构可以任意大,因此结构返回值不一定适合机器的任何寄存器。但是C语言定义说,您可以从函数返回结构值,并让它正常工作,所以编译器必须为您做一些额外的工作,以确保有一些安全的地方可以将返回值传输回调用方。

例如,假设您编写

代码语言:javascript
复制
struct person {
    char firstname[100];
    char lastname[100];
};

struct person f5() {
    struct person ret;
    strcpy(ret.firstname, "Akshay");
    strcpy(ret.lastname, "Immanuel");
    return ret;
}

这看起来可能很危险(尤其是如果您还记得前面的示例f4()是如何不工作的),但事实证明,它是完全可以的。

脚注。实际上,我的示例在另一种方式上是危险的,因为它在使用strcpy将字符串复制到firstnamelastname时不检查溢出。

假设您从其他地方调用此函数:

代码语言:javascript
复制
struct person x;
x = f();

这是怎么回事?这取决于编译器;不同的编译器以不同的方式完成它。一种方法是编译器本质上假装您编写函数的方式不同。它假装你写了

代码语言:javascript
复制
void f5(struct person *retp) {
    struct person ret;
    strcpy(ret.firstname, "Akshay");
    strcpy(ret.lastname, "Immanuel");
    *retp = ret;
}

然后当你叫它的时候,它假装你写了

代码语言:javascript
复制
struct person x;
f5(&x);

但关键是你不必这样写;编译器在你的背后为你做了所有的事情。

票数 10
EN

Stack Overflow用户

发布于 2016-01-30 10:28:10

对于简单的小类型,如整数、浮点类型和指针,该值将在机器寄存器中返回。

对于结构等复杂类型,调用方保留堆栈上的空间,被调用方将结果存储在那里。由于调用方负责释放框架,因此在何时处理结果取决于调用方。

注意:即使是结构也可以在寄存器中返回,只要它适合。但是它依赖于平台和ABI规范。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35100462

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档