• 函数返回值传递


    出自《程序员的自我修养-链接、装载与库》P299

    eax是函数传递返回值的一个通道。

    1.对于小于4个字节的数据函数将返回值存储在eax中。

    2.5~8个字节对象的情况调用惯例都是采用eax和edx的联合返回方式进行。

    3.大于8个字节的返回类型,用一下代码测试:

     1 typedef struct big_thing
     2 {
     3     char buf[128];
     4 }big_thing;
     5 
     6 big_thing return_test()
     7 {
     8     big_thing b;
     9     b.buf[] = 0;
    10     return b;
    11 }
    12 
    13 int main()
    14 {
    15     big_thing n = return_test();
    16 }
    • 首先main函数在栈额外开辟了一片空间,并将这块空间的一部分作为传递返回值的临时对象,这里称为temp
    • 将temp对象的地址作为隐藏参数传递个return_test函数
    • return_test 函数将数据拷贝给temp对象,并将temp对象的地址用eax传出。
    • return_test返回以后,mian函数将eax 指向的temp对象的内容拷贝给n。

    如果返回值的类型的尺寸太大,c语言在函数的返回时会使用一个临时的栈上内存作为中转,结果返回值对象会被拷贝两次。因而不到万不得已,不要轻易返回大尺寸对象。

    再来看看函数返回一个C++对象会如何:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 struct cpp_obj
     5 {
     6     cpp_obj()
     7     {
     8         cout << "ctor
    ";
     9     }
    10 
    11     cpp_obj(const cpp_obj& c)
    12     {
    13         cout << "copy ctor
    ";
    14     }
    15 
    16     cpp_obj& opearator=(const cpp_obj& rhs)
    17     {
    18         cout << "operator = 
    ";
    19         return *this;
    20     }
    21 
    22     ~cpp_obj()
    23     {
    24         cout << "dtor
    ";
    25     }
    26 };
    27 
    28 cpp_obj return_test()
    29 {
    30     cpp_obj b;
    31     cout << "before return
    ";
    32     return b;
    33 }
    34 int main()
    35 {
    36     cpp_obj n;
    37     n = return_test();
    38 }

    运行后的输出结果可以得出:函数返回之后,进行了一个拷贝函数的调用,以及一次operator=的调用,也就是说,仍然产生了两次拷贝。因此C++的对象同样会产生临时对象。

    在这段代码中我们还能看到在c++返回一个对象时,对象要经过两次拷贝构造函数的调用才能够完成返回对象的传递,1次拷贝到栈上的临时对象里,另一次把临时对象拷贝到存储返回值的对象里。在某些编译器里,返回一个对象甚至要经过更多的步骤。

    为了减少返回对象的开销,C++提出了返回值优化(RVO)技术,可以将某些场合下的对象拷贝减少一次,例如:

    1 cpp_obj return_test()
    2 {
    3     return cpp_obj();
    4 }

    目的是直接将对象的构造在传出时使用的临时对象上,减少一次复制过程。

  • 相关阅读:
    嘿,新年快乐
    最近无状态~
    奥巴马:我们为什么要上学
    大学学不会逃课是不会有出息的!
    赫赫,给红十字捐款的sb了吧
    狄仁杰你敢不装逼吗
    腾讯qq开始耍威胁用户的无赖手段了
    <转>关于信仰
    恩,老了~~~
    Vue 2.0学习笔记: Vue中的computed属性
  • 原文地址:https://www.cnblogs.com/bugershang/p/3265729.html
Copyright © 2020-2023  润新知