理解C++ lvalue与rvalue

转载 2018年04月17日 08:57:36

来源:https://www.cnblogs.com/kinsang/p/6855579.html

一个众所周知的危险错误是,函数返回了一个局部变量的指针或引用。一旦函数栈被销毁,这个指针就成为了野指针,导致未定义行为。而左值(lvalue)和右值(rvalue)的概念,本质上,是理解“程序员可以放心使用的变量”。

 

空泛的讨论先到这里,先看一段会报错的代码:

复制代码
#include <iostream>

using std::cout;
using std::endl;

int foo(int &a) {
    return a;
}

int main() {
    int a = 1;
    cout << &a << endl;
    int *p = &foo(a);
}
复制代码

这里,对foo(a)取地址会引起错误: "lvalue required as left operand of assignment".字面理解是,&取地址运算符只能获取左值的地址。

毫无疑问的是,foo(a)的值是存在的,是数值1。之所以报错,是因为编译器认为它不是左值,不允许程序员获取它存放的地址。

 

我对这点标准的理解是:

获取一个临时空间的地址通常意味着要对这块内存赋值。在C++程序中,临时空间的销毁时机是不确定(undefined)的,它随时被用于其他临时空间的存储。于是程序员不允许使用这块空间。联系之前总结的堆栈概念,可以对C++中的变量存储有更深的理解。

 

堆栈概念一文,我小结了C++程序中数据可以存在三个地方:

1. 函数栈,在函数体内的定义的变量

2. 堆,特别指使用new,malloc获取的内存空间

3. 静态数据区,即.data 和.bss

 

对于lvalue的通俗描述,是“具有确定地址的非临时对象”,而不满足lvalue定义的值均被认为是rvalue。换句话说,C++程序里面出现的值,非左即右。下面我们分析一下这三个存放数据的区域里面可以被使用的值的情况:

堆的空间上的变量完全由程序员申请和管理的,所以它们都有明确的地址,是可以放心使用的左值。

静态数据区

对于静态数据区,尽管存放的位置是固定的,但里面的数据并不能认为都是左值。主要是因为里面有“字面值”,包括const所实现的常量,即静态存储而不能被修改的值。

函数栈

当函数调用发生的时候,系统会创建函数栈,保留上下文,函数调用结束的时候,函数栈内的变量会被销毁。函数体里面定义的变量是左值,而临时变量是右值。

 

拓展

C++ 11标准,为了更好地利用临时变量,提出Rvalue Reference,对应的的实现是move semantics (转移语意)和Perfect Forwarding(完美转发)。对这些新特性还不了解,暂时不写。

 

参考:

http://www.cnblogs.com/dejavu/archive/2012/09/02/2667640.html

http://stackoverflow.com/questions/230584/where-are-variables-in-c-stored

http://eli.thegreenplace.net/2011/12/15/understanding-lvalues-and-rvalues-in-c-and-c

MFC编程中“占位符和动态创建”技巧的应用

 刘勇  夏安邦       在MFC编程中,“占位符和动态创建”技巧的应用是十分广泛的,虽然在有些编程书籍和文章中有所涉及,但缺乏系统的介绍和必要的总结,给应用带来不便。本文将对这方面的编程技巧进行...
  • think77
  • think77
  • 2001-01-06 16:43:00
  • 735

理解lvalue和rvalue

分析了lvalue和rvalue的特征,深度理解他们的使用限制。
  • rogerhe
  • rogerhe
  • 2011-05-11 09:24:00
  • 1825

C++ - 左值(lvalue)引用和右值(rvalue)引用 的 区别

左值(lvalue)引用和右值(rvalue)引用 的 区别   左值引用, 即&i, 是一种对象类型的引用; 右值引用, 即&&i, 是一种对象值的引用; std::move()可以把左值引用, 转...
  • u012515223
  • u012515223
  • 2013-11-10 16:57:37
  • 4486

C++中rvalue和lvalue详悉

以下内容是参考书籍以及晚上的内容,整理而成,仅供参考~~ lvalue和rvalue 在计算机的远古时代,变量的lvalue和rvalue是指: lvalue:变量在内存中的位置。通过它能够...
  • piaoxuezhong
  • piaoxuezhong
  • 2017-03-06 15:11:06
  • 900

[C/C++不常见语法特性]_[初级]_[左值-右值-lvalue-rvalue]

场景: 1. C++11 引入了std::move,它可以高效率的从一个左值资源移动到另一个左值资源里, 这个过程不需要再创建新的资源. 这对std::string,std::vector这种标...
  • infoworld
  • infoworld
  • 2016-02-18 14:45:28
  • 2347

cppreference.com关于值类型的详细解读:lvalue,rvalue,xvalue,prvalue,glvalue

基本值类型与表达式的两个属性相对应: 1) 有"身份"[has identity]:能够确定某个表达式是否和另一个表达式指涉[refers to]同一个实体,例如,通过比较它们标识[identify]...
  • yanglingwell
  • yanglingwell
  • 2016-04-17 13:58:56
  • 116930

C和C++里面的lvalue 和 rvalue的释义

在看GCC的文档的时候,看到一个词lvalue,查了金山词霸其释义为 lvalue [计] 左值。因为的确在介绍编译原理的课程中听过这个词,大致知道其意思就没有多想。但是看完GCC文档的这个篇幅,都无...
  • Borenbao
  • Borenbao
  • 2006-08-25 14:13:00
  • 1481

lvalue,rvalue,xvalue,gvalue,prvalue到底怎么区分

在C11中,开始大量使用lvalue,rvalue,xvalue,gvalue,prvalue,已经由此带来的左值引用,右值引用。 gvalue,rvalue属于派生概念。关键还是lvalue,prv...
  • z_yu_yun
  • z_yu_yun
  • 2017-02-27 17:22:47
  • 396

C++ Cheat Sheet (keep updating ...)

有一阵子没有关注C++了,随着年纪增长记忆力下降,感觉需要一个小抄记录些C++的知识可以随时查阅,碰到什么值得记录知识点就记录在这里,时不时更新下这个文档。...
  • macchan
  • macchan
  • 2017-12-31 11:50:13
  • 45

lvalue and rvalue

Every C++ expression is either an lvalue or an rvalue. An lvalue refers to an object that persists b...
  • u011881943
  • u011881943
  • 2013-12-30 15:01:00
  • 642
收藏助手
不良信息举报
您举报文章:理解C++ lvalue与rvalue
举报原因:
原因补充:

(最多只允许输入30个字)