尝试学习lvalues
,rvalues
和内存分配。因此,有很多学习材料会有一些混乱。
rvalue
是一个值,只需要在创建它的表达式的边界中存在(至少在C ++ 11之前)。所以它有一个占据的地址和内存块。但根据定义,我们无法获得rvalue
的地址,因为与lvalue
相比,它是一个临时对象。
但即使在C ++ 11之前,我们也可以通过从函数返回并将其保存为const引用类型(呃,我猜不是地址而是值)来获取rvalue
的地址。
那么,更确切地说,rvalue
分配如何工作?程序或操作系统在多长时间内真正记住创建rvalue
并标记为已分配且另一个对象无法取代的内存位置?
我如何看待它,现在rvalues
就像lvalues
一样存储,但我们只是拥有其他权限来访问它们。并且他们有其他类型的释放 - 对于lvalues
超出范围,rvalues
可以通过存在于表达式边界或直到没有更多链接来优化。
答案 0 :(得分:8)
简短回答:它依赖于实现。
这背后的主要原因是编译器始终可以自由地提高代码的性能。理解这一点的一个更具体的方法是记住,一个值可以存储在CPU的寄存器中,而不是实际存在于您的内存中,这或多或少意味着该值没有地址。我不会打赌我所拥有的一切,但这可能是“我们无法获得右值地址”的主要原因之一。
以更一般的方式,因为rvalue在语义上是临时的,所以更有可能放在临时位置或以不能轻易映射到地址的方式进行优化,即使它可能会产生相反的效果表现。
答案 1 :(得分:6)
从概念上讲,rvalues存在于"堆栈"。如果你到达他们的地址,它在概念上是堆栈中的某个地址。如果地址根本没有被采用,只要编译器设置正确的指令使其显示为就像它被创建一样,实体可能永远不会真正存在。
即使真正创建实体的位置取决于各种各样的东西,它甚至可能最终不在堆栈中:它可能在当前堆栈帧中,但它也可能是其他堆栈帧或如果rvalue最终被复制/移动到那里并且编译器执行copy-elision,则在某些目标中。如果rvalue最终被绑定到const&
,那么它也可能位于其他地方,而不是它没有。
rvalue的生命周期受语言规则的约束。实际实现的方式在很大程度上取决于编译器和/或它所遵循的ABI。