C++中的rvalue如何在内存中存储?

14

试图学习 lvaluervalue及它们的内存分配。然而,有很多混乱的学习材料。

rvalue是一种仅在创建它的表达式范围内需要存在的值(至少在C++11之前是这样)。因此,它有一个地址和占用的一块内存。但根据定义,我们不能获取rvalue的地址,因为它是一个临时对象,与lvalue相反。然而,即使在C++11之前,我们也能通过将其从函数返回并保存到const引用类型中来获取rvalue的地址(嗯,我想不是地址,而是值)。

那么,更准确地说,rvalue的分配是如何工作的?程序或操作系统真正记住了rvalue创建的内存位置以及标记为已分配的时间有多长,以至于另一个对象不能取代它?

从我的角度来看,现在rvalues的存储方式就像lvalues一样,只是我们有其他访问它们的权利。它们有其他类型的释放方式-对于lvalues,当超出作用域时释放;对于rvalues,可能通过存在于表达式边界或者没有更多链接到它的方式进行优化释放。


8
lvalues 和 rvalues 是表达式的分类。它们不使用任何存储空间。使用存储空间的是对象。(有时是引用)。您似乎在写 "rvalue",但实际上您指的是 "临时对象"。 - M.M
我认为rvalue根本不需要地址。它们可以在寄存器中进行评估。 - user1196549
1
@M.M 这应该是正确的答案。 - Ivan Aksamentov - Drop
@Drop well - 我认为OP是想问关于临时对象的问题,而我的评论并没有回答这个问题,只是澄清了术语。 - M.M
2个回答

12

简短回答:这取决于实现。

主要原因在于编译器可以自由地优化您的代码性能。更具体地理解这一点的方法是记住:一个值可以存储在CPU的寄存器中,实际上从未在内存中,这或多或少意味着该值没有地址。我不会把所有东西都压在它身上,但这可能是“我们无法获取rvalue的地址”的主要原因之一。

以更一般的方式来看,由于rvalue在语义上是临时的,因此更有可能被放置在临时位置或以无法轻松映射到地址的方式进行优化,即使可以,从性能上讲也是适得其反。


9
从概念上讲,rvalues 存在于 "堆栈" 上。如果你得到它们的地址,这个地址从概念上来说是在堆栈的某个地方。如果地址根本没有被占用,只要编译器设置正确的指令,实体就可能永远不会真正存在,好像它已经被创建出来一样。
即使实体确实被创建了,它所在的位置取决于各种因素,甚至可能根本不在堆栈上: 它可能在当前堆栈帧中,但也可能是其他堆栈帧或某个目标中,如果 rvalue 最终被复制/移动到那里并且编译器进行了副本省略。如果 rvalue 最终被绑定到一个 const&,它的存储位置也可能与没有绑定时不同。
rvalue 的生命周期受语言规则约束。它如何实际实现基本上取决于编译器和/或遵循的 ABI。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接