函数返回值优化? [英] Function return value optimization?

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

问题描述

我正在编写我自己的编程语言,由于各种原因,它被编译成C语言(其中一个原因是我对汇编几乎一无所知)。

我有一个关于编译器(比如GCC或Clang)如何优化从函数返回值的问题。假设我有这样的代码:

int FUNC()
{
    int A = 3;
    return A;
}

int main()
{
    int B = FUNC();
}

我的理解是,您希望变量A在从FUNC返回时被复制到B(如果A和B是结构,这可能会很昂贵)。编译器是否会意识到,在这种情况下,B可以只指向A所在的任何位置,并且不需要副本?

如果main()如下所示:?

int main()
{
    int C;
    C = FUNC();
}

谢谢!

推荐答案

基本上有两种情况。(1)返回值不是结构,(2)返回值是结构。

对于情况(1),返回值通常在寄存器中--过去总是r0,或者在浮点返回的情况下可能是f0,或者在long int返回的情况下可能是r0+r1。

在这种情况下,当您有类似

int a()
{
    return 3;
}

int b()
{
    return a();
}
编译器基本上将b()编译为调用函数a的代码,仅此而已。函数a在任何int值函数返回的寄存器中返回它的值,而这正是函数b返回它的位置,所以没有其他事情可做;该值已经在它所属的位置。因此,至少在这种情况下,不会涉及额外的复制。

(这也可能导致代码看起来像是错误的代码,因此这个常见问题:Function returns value without return statement?。)

但是,在您的函数main中,如果您执行了int B = b(),那么是的,可能存在从返回寄存器到B位置的复制。(不过,目前,聪明的编译器可能会记住r0B。)

另一方面,对于结构(即第二种情况),尤其是对于较大的结构,编译器通常会传递一个额外的隐藏参数,该参数是指向调用方中返回值应该到达的位置的指针。也就是说,如果您有

struct largestruct bb();

int main()
{
    struct largestruct B;
    B = bb();
}

它或多或少会被编译,就像您编写的

void bb(struct largestruct *);

int main()
{
    struct largestruct B;
    bb(&B);
}

所以如果您有

extern struct largestruct aa();

struct largestruct bb()
{
    return aa();
}

可能会像编写时一样进行编译

extern void aa(struct largestruct *);

void bb(struct largestruct *__retp)
{
    aa(__retp);
}

同样,指针指向正确的位置,不需要任何副本。

这篇关于函数返回值优化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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