即日起在codingBlog上分享您的技术经验即可获得积分,积分可兑换现金哦。

c语言函数返回值相关疑难问题

编程语言 wanna_wsl 13℃ 0评论

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)具名返回值优化


    这种优化是甚至连被调函数中的局部变量都不要了!直接在主调函数中操作对象(根据隐藏参数传入的对象的引用)。

转载请注明:CodingBlog » c语言函数返回值相关疑难问题

喜欢 (0)or分享 (0)
发表我的评论
取消评论

*

表情