c语言函数返回值问题

来源:互联网 发布:w 是什么矩阵 编辑:程序博客网 时间:2024/05/19 18:42

C语言中,调用函数结束时,如果有返回值,会涉及到函数返回值传递问题,根据返回值的大小,会有不同的处理方式。
一、返回值小于等于4个字节
函数执行完毕后,如果返回值小于等于4字节,则会将值保存在寄存器eax中,然后在调用函数中通过读取eax的值来获得返回值。
二、当返回值大小在[5, 8]字节范围内时
因为eax寄存器只有四个字节,因此,当返回值在[5, 8]字节范围内时,一般采用eax和edx联合返回的方式进行的。其中eax存储返回值的低4字节,edx存储返回值的高4字节。
三、当返回值大于8个字节时
当返回值大于8个字节时,如返回较大的结构体,编译器会做如下处理:

  • 主调函数在其栈中的局部变量区域中额外开辟一片空间,将其一部分作为传递返回值的临时对象temp。
  • 将temp对象的地址作为隐藏参数传递给被调函数函数。
  • 被调函数函数将数据拷贝给temp对象,并将temp对象的地址用eax传出。
  • 被调函数返回后,主调函数将eax指向的temp对象的内容拷贝给n。
    这里写图片描述

总结:

  • C语言对于小于8字节的返回值,以寄存器为中转。大于8字节的,以主调函数中新开辟的同样大小的中间变量temp为中转。故不到万不得已,不要轻易返回大尺寸对象。
  • C++函数的返回值传递大返回值略有不同,其可能是像C那样,1次拷贝到栈上的临时对象里,然后把临时对象拷贝到存储返回值的对象里。但,有些编译器会进行返回值优化RVO(Return Value Optimization),这样,对象拷贝会减少一次,即没有临时对象temp了,直接拷贝到主调函数的相应对象中。
  • C++对于返回值还有一种更“激进”的优化策略——NRV(Named Return Value)具名返回值优化
    这种优化是甚至连被调函数中的局部变量都不要了!直接在主调函数中操作对象(根据隐藏参数传入的对象的引用)。
0 0
原创粉丝点击