• c++函数返回的过程


    int power(int x) {
        return x * x;
    }
    
    int main()
    {
        int x = power(2);
    
        //cout << v.str[0] << endl;
        return 0;
    }

    对于返回值比较偏小的函数,直接将返回值保存至寄存器。

    这里先将x的值保存至eax中,在用imul指令计算x*x的值(eax = eax * x)。函数返回后直接从eax中取回结果。

    如果结果比较大,无法将结果保存至寄存器中,那只能将结果的地址保存至寄存器中。

    struct Node {
        char str[100];
    };
    
    Node fun() {
        Node n;
        n.str[0] = 'o';
        return n;
    }
    
    int main()
    {
        Node x = fun();
    
        return 0;
    }

    首先观察fun函数返回的过程:

    使用rep movs将n按字节拷贝至rbp+170h的地址(拷贝的长度由ecx决定),将返回的地址保存至rax中。

    再看获取fun返回值的过程:

    将返回的地址从rax中取出,再拷贝至x中。

    也就是说这个过程将返回的结构体拷贝了2次。。。从n拷贝到temp,再从temp拷贝到x。

    在C++11中提供了RVO/NRVO机制可以防止这种重复拷贝开销。另一种是RVO/NRVO机制实现复制消除机制。

    RVO机制使用父栈帧(或任意内存块)来分配返回值的空间,来避免对返回值的复制。也就是将Base fun();改为void fun(Base &x);

    Base fun(int n) {
        return Base();
    }
    
    Base x = fun();

    这段代码输出为:

    Base()

    ~Base()

    但如果代码产生了改动,编译器无法知道应该防止哪个对象作为返回值,就无法触发RVO机制:

    Base fun(int n) {
        Base a,b;
        if (n % 10 == 1) {
            return a;
        }
        else {
            return b;
        }
    }
  • 相关阅读:
    Java 位运算符和移位运算符
    String类为什么是final
    SVN server 安装 并创建用户访问
    初学JavaScript正则表达式(十一)
    初学JavaScript正则表达式(十)
    初学JavaScript正则表达式(九)
    初学JavaScript正则表达式(八)
    初学JavaScript正则表达式(七)
    初学JavaScript正则表达式(六)
    初学JavaScript正则表达式(五)
  • 原文地址:https://www.cnblogs.com/HadesBlog/p/12790314.html
Copyright © 2020-2023  润新知