c++ - 赋值语句中关于左值和右值的疑惑
高洛峰
高洛峰 2017-04-17 13:27:56
0
5
623

对于左值和右值还有一些模糊的地方:

书上说左值(L-value)是指地址值,右值(R-value)是指数据值。
但对于***右值指的是引用了一个存储在某个内存地址里的数据***这句话不是特别清楚,比如说:a = 5, 
                1、数值5是来自于内存中的某个特定存储区域吗,而且无论数值大小均是这么来的吗(记忆中好像不是的呢)?
                2、使用数值5的时候是以copy的方式还是其他的方式得到的?
                3、或者是在赋值之前临时创建的大小为int的空间来存储5,并非是从内存中的引用?
                4、关于这方面有什么相关的书籍推荐么?
                

先谢谢各位不吝赐教。

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

reply all(5)
PHPzhong

This kind of constants are in the code section (.text section).
Recommended: In-depth understanding of computer systems

Ty80

I am not very proficient in C language, but I would like to share my understanding here. Please point out if there is anything incorrect.

  1. Personally, I feel that "rvalue" should not just refer to the data in the memory address. For example, a = 5, 5 is a direct number rather than a memory address. Just as in assembly, you can write direct numbers directly to registers, or you can write numbers in memory addresses. Because it is meaningless to directly count the address.

  2. I only know that when java in String is directly assigned to a string, the string shares the string in the constant pool, but I don’t know if there is a similar mechanism in C language. For assignments like a = 5, it should be similar to direct immediate data writing; for assignments like int a;int b = 5; a = b;, it should be a copy. At this time, b means "referencing data in a certain memory address".

  3. Personally, I feel that for this simple assignment, it is not necessary to temporarily create space storage and copy it there (I have not verified it).

  4. I don’t usually use C, and I don’t study it deeply enough to give valuable recommendations.

The above are personal opinions and have not been verified. They are provided for reference by the subject. Please point out any errors.

大家讲道理

I don’t know what book you are reading, I don’t quite understand the definition of address value and data value

一个左值可能是一个函数或者对象。
一个右值可能是一个对象、临时对象或者临时对象的子对象、或者不是对象的值
具体可以参阅标准3.10小节,讲的就是左值与右值

As for the memory location where 5 is located, for this kind of integer, the compiler usually uses an immediate value to directly assign the value. 5 does not temporarily exist anywhere.
It is like putting 5 in The position on the stack where a is located, then this sentence is a = 5;
If it is a string, it may be stored in other locations such as code segments, and then copied, so that it is str = "123143";

刘奇

I don’t know much about other things
But:
Lvalue and rvalue are both for expressions. lvalue refers to the persistent object that still exists after the expression ends, and rvalue refers to the expression. A temporary object that ceases to exist when the expression ends.
A convenient way to distinguish lvalues ​​and rvalues ​​is to see if the address can be taken from the expression. If so, it is an lvalue, otherwise it is an rvalue

阿神

I’m not sure whether the questioner is asking about C or C++. If it is C++, which version of standard C++ is it. I will only talk about the issues about lvalues ​​and rvalues ​​in C++11 here.

Roughly speaking, when an object is used as an rvalue (rvalue), the value of the object (its content) is used; when an object is used as an lvalue (lvalue), the value of the object is used. is the identity of this object (its location in memory).

For the expression a = 5;, assume that a is of type int. The expression a on the left side of the equal sign is of type lvalue, because we need to use its identity (its location in memory) to assign a value to it. The expression 5 on the right side of the equal sign is of type rvalue because we need to use its value (its content).

1. Does the value 5 come from a specific storage area in the memory, and does it come from this regardless of the value (it doesn’t seem to be the case in the memory)?

The value 5 is a literal, its type is rvalue (more accurately, prvalue, see below) and should be stored in static memory. This is true regardless of size, as long as it is literal, such as 2333333333333333ULL.

2. When using the value 5, is it obtained by copying or other methods?

In the expression a = 5;, it should be the built-in assignment operator that copies 5 from static memory into the variable a.

For custom assignment operators, it depends on: 1. Whether the copy-assignment operator (copy-assignment operator) and move-assignment operator (move-assignment operator) are defined, 2. The expression on the right side of the equal sign The value type to determine whether to copy or move.

3. Or is the space of size int temporarily created before assignment to store 5, not a reference from memory?

No.

4. Are there any relevant books recommended in this regard?

I don’t know if there are any books specifically discussing this, but you can take a look at the documentation and the C++11 standard in the reference section at the end of this article.


The following is extended content.

Premise

Expressions (expressions, such as operators and their operands, variable names, etc.) in C++ are classified according to two aspects: type and value category. Every expression must belong to one of the three main value categories (see below).

Value categories for expressions in C++11

Before C++11, the value categories of expressions were divided into lvalue (lvalue) and rvalue (rvalue). Since C++11, the value categories of expressions are divided into lvalue, xvalue, There are five types: prvalue, glvalue, and rvalue. The reason why so many value types were introduced is because of the new move semantics in C++11.

The relationship between them is as shown below:

           expression
               |
        +------+-------+
        |              |
        v              v
     glvalue         rvalue        <-- 混合值类别(mixed value categories)
        |              |
  +-----+-----+  +-----+-----+
  |           |  |           |
  v           v  v           v
lvalue       xvalue       prvalue  <-- 主要值类别(primary value categories)
The criteria for classifying the value category of an expression are two points:

  • Has identity That is, whether it is possible to determine whether two expressions are the same expression by comparing their identities.

  • can be moved from That is, the value of the expression can be moved to other variables, leaving the original variable in an uncertain but valid state ( For example, it can be destructed normally).

The relationship between these 5 value categories is shown in the following table:

|   value    | has identity | can be moved from |
+============+==============+===================+
|   lvalue   |     yes      |        no         |
|   xvalue   |     yes      |        yes        |
|  prvalue   |     no       |        yes        |
| (not used) |     no       |        no         |
+------------+--------------+-------------------+
|  glvalue   |     yes      |        ?          | pre-C++11 lvalue
|   rvalue   |     ?        |        yes        | pre-C++11 rvalue

C++11 standard original text

From C++11 standard § 3.10

— An lvalue (so called, historically, because lvalues ​​could appear on the left-hand side of an assignment expression) designates a function or an object. [ Example: If E is an expression of pointer type, then *E is an lvalue expression referring to the object or function to which E points. As another example, the result of calling a function whose return type is an lvalue reference is an lvalue. —end example ]
— An xvalue (an “eXpiring” value) also refers to an object, usually near the end of its lifetime (so that its resources may be moved, for example). An xvalue is the result of certain kinds of expressions involving rvalue references (8.3.2). [ Example: The result of calling a function whose return type is an rvalue reference is an xvalue. —end example ]
— A glvalue (“ generalized” lvalue) is an lvalue or an xvalue.
— An rvalue (so called, historically, because rvalues ​​could appear on the right-hand side of an assignment expression) is an xvalue, a temporary object (12.2) or subobject thereof, or a value that is not associated with an object.
— A prvalue (“pure” rvalue) is an rvalue that is not an xvalue. [ Example: The result of calling a function whose return type is not a reference is a prvalue. The value of a literal such as 12, 7.3e5, or true is also a prvalue. —end example ]

Reference

  • Categories of value of expressions in C++: Value categories

  • The origin of the change in C++’s value classification name: “New” Value Terminology

  • C++0x to C++11 value class name change: n3055

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!