C++ 为什么文字和临时变量不是左值?
我已经读到,C++ 为什么文字和临时变量不是左值?,c++,c++11,rvalue,lvalue,C++,C++11,Rvalue,Lvalue,我已经读到,左值是“具有定义存储位置的东西” 而且,文字和时间变量不是左值,但没有给出这种说法的理由 是因为文字和临时变量没有定义存储位置吗?如果是,那么如果不在内存中,它们驻留在哪里 我认为“定义的存储位置”中的“定义”有一定的意义,如果有(或没有),请告诉我 如果不在内存中,它们驻留在哪里 当然,它们驻留在内存中*,这是无法避免的。问题是,您的程序能否确定它们在内存中的确切位置。换句话说,您的程序是否允许获取问题所在的地址 在一个简单的例子a=5中,5的值或表示赋值为5的指令位于内存中的某个
左值
是“具有定义存储位置的东西”
而且,文字和时间变量不是左值,但没有给出这种说法的理由
是因为文字和临时变量没有定义存储位置吗?如果是,那么如果不在内存中,它们驻留在哪里
我认为“定义的存储位置”中的“定义”有一定的意义,如果有(或没有),请告诉我
如果不在内存中,它们驻留在哪里
当然,它们驻留在内存中*,这是无法避免的。问题是,您的程序能否确定它们在内存中的确切位置。换句话说,您的程序是否允许获取问题所在的地址
在一个简单的例子a=5
中,5的值或表示赋值为5的指令位于内存中的某个位置。但是,您不能使用5的地址,因为int*p=&5
是非法的
请注意,字符串文字是“非左值”规则的一个例外,因为const char*p=“hello”
生成字符串文字的地址
*然而,它不一定是数据存储器。事实上,它们甚至不可能在程序内存中表示为常量:例如,赋值
short a;a=0xFF00
可以表示为在上八位字节中分配0xFF
,并清除内存中的下八位字节
而且,文字和时间变量不是左值,但没有给出这种说法的理由
这适用于除字符串文字外的所有临时文字和文字。这些实际上是左值(如下所述)
是因为文字和临时变量没有定义存储位置吗?如果是,那么如果不在内存中,它们驻留在哪里
对。文字2
实际上并不存在;它只是源代码中的一个值。因为它是一个值,而不是一个对象,所以它不需要与任何内存关联。它可以硬编码到编译器创建的程序集中,也可以放在某个地方,但由于不一定要放在某个地方,所以您所能做的就是将其视为纯值,而不是对象
不过还有一个例外,那就是字符串文字。因为字符串文字是const char[N]
的数组,所以它们实际上有存储空间。您可以获取字符串文本的地址,字符串文本可以衰减为指针,因此它是一个左值,即使它没有名称
临时值也是右值。即使它们作为对象存在,它们的存储位置也是短暂的。它们只会持续到它们所处的完整表达结束。你不允许带他们的地址,他们也没有名字。它们甚至可能不存在:例如,在
Foo a = Foo();
可以删除Foo()
,并将代码语义转换为
Foo a(); // you can't actually do this since it declares a function with that signature.
因此,优化后的代码中甚至没有一个临时对象
为什么文字和临时变量不是左值
我有两个答案:一是因为它没有意义(1),二是因为标准上这么说(2)。让我们关注(1)
是因为文字和临时变量没有定义存储位置吗
这是一个不适合这里的简化。一种简化:文字和临时值不是左值,因为修改它们没有意义1
什么是5++
?rand()=0
的含义是什么?标准规定,临时值和文本不是左值,因此这些示例无效。而且每个编译器开发人员都更快乐
1) 您可以定义和使用用户定义的类型,修改临时类型是有意义的。这个临时的将一直存在到完整表达式的评估。François Andrieux在调用
f(MyType{}.mutate())
和f(my_int+1)
之间做了一个很好的类比。我认为简化仍然保持不变,因为MyType{}。mutate()
可以被视为另一个临时变量,就像MyType{}
was一样,就像myint+1
可以被视为另一个int
一样。这都是基于语义和观点的。真正的答案是:(2)因为标准是这样说的。lvalue
代表定位值,表示在内存中占据某个可识别位置的对象
术语定位器值也用于:
C
C编程语言遵循类似的分类法,只是
赋值的作用不再重要:C表达式是
分类为“左值表达式”和其他(函数和
非对象值),其中“左值”表示标识
一个对象,一个“定位器值”[4]
所有不是左值的东西都是排除在外的右值。每个表达式都是lavalue
或rvalue
最初,C中使用了lvalue
术语来表示可以保留在赋值运算符左侧的值。然而,随着const
keywork,这一点发生了变化。并非所有的左值都可以分配给。那些可以被称为可修改的左值
而且文字和时间变量不是左值,而是
对此声明没有给出任何理由
根据文字,在某些情况下,左值可以是
- 标量类型的文本是
rvalue
,因为它们的大小已知,很可能直接嵌入给定硬件体系结构上的机器命令中。5
的内存位置是什么
- 相反,奇怪的是,字符串
int a =5;
int b = 3;
int c = a+b;
int c = 6;
&c = 4; //ERROR: &c is an rvalue
int arr[] = {1, 2};
int* p = &arr[0];
*(p + 1) = 10; // OK: p + 1 is an rvalue, but *(p + 1) is an lvalue
int *p = &5; // not allowed due to category rules
*p = 6; // oops, dangling pointer
template<typename T> auto f(T&&t) -> T& { return t; }
// ...
int *p = f(5); // Allowed
*p = 6; // Oops, dangling pointer, no compiler error message.