c语言函数的返回值是地址,函数的返回值没有地址吗?为什么?

博客探讨了C语言中函数返回值是否有地址的问题,指出返回值的地址取决于类型,C11标准规定某些情况下返回值具有临时生命周期。文章通过实例分析了编译器如何处理这个问题,并强调程序员应关注文法的正确性,底层实现由编译器负责。
摘要由CSDN通过智能技术生成

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

其实这种语言层面的东西,看汇编之类的是没有多大意义的,因为是标准决定实现,而不是实现决定标准,不应该本末倒置。就你所提到的“函数的返回值是否有地址”,我的看法是:未知。首先,函数的返回值是一个右值,而右值的一个特点是不能用 & 取其地址。(例如返回一个 int 的函数,看汇编的话如上面所说,返回值直接通过寄存器传递)但这不一定代表返回值没有地址,如 struct a { int n[1]; }; struct a f(void) { return (struct a) { { 123 } }; },这个函数返回了一个结构体,结构体本身是右值,所以里面的成员也都是右值,没法取地址。但这里面有个数组对象,而 C 语言规定,数组对象可以转换成指向其首元素的指针,于是,通过 f().n,是可以获取到数组首元素的地址的。再根据结构体和数组的特性,获取到的也就是所谓函数返回值的地址。当然,你是不可能修改该指针指向的对象的,这是未定义行为。但关于用这个指针访问函数的返回值,不同年代的 C 语言标准对此有不同的定义。C99 规定,不能在函数返回后的下一个序列点后访问函数的返回值,否则是未定义行为(可惜 C99 没能说清楚这个指向返回值的指针到底是什么情况)。而 C11 规定的比较详细:如果出现这种能取返回值地址的情况(即这个结构体为右值),则这个指针指向一个具有临时生命周期的对象。所谓的临时生命周期,开始于函数返回后的那一瞬间,结束于一个完整表达式的执行完毕。那么,从 C11 的角度,可以认为:一个返回值是否拥有地址,是由其返回值的类型决定的。(我在 x86-64 gcc 9.2 平台上对上面那个 f 进行了反汇编,它其实也仅仅使用了寄存器保存返回值。而在代码用到指向 f 的返回值的指针时,编译器为了符合标准,为返回值开辟了一块内存,把寄存器的值移到这块内存里,并用了这块内存的地址作为返回值的地址)其实,最终要不要地址、要的是什么地址,甚至是要不要返回值,这种底层的事情编译器都会帮你料理好,你只管文法上的正确性即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值