Essence of C/C ++ left
(1) past and present on the left
The left value (lvalue) is the attribute of the C/C ++ expression. Only one expression can be used to talk about its left value.
The left value has been around for a long time. It existed before the emergence of the world's first c Standard c89. Early definitions were based on the requirements of built-in value assignment operators. The expression of the left operand that can be used as the value assignment operator belongs to the left value and can only be used as the expression of the right operand belongs to the right value (Rvalue ), the left and right characters in the left and right values come from this.
However, the early definition of the Left value is too rough, which leads to great limitations and some phenomena cannot be explained. For example, the array name, which belongs to the aggregation type and is not a scalar type, cannot be expressed as a numerical value, while the value assignment operator requires the operand to be a scalar type (the structure is a special case ), the assignment of arrays as the left operand of the assignment operator is obviously unreasonable. Therefore, the array name belongs to the right value in the early definition of the Left value. On the other hand, the array is used as the complete object, it should be possible to perform the address fetch operation. However, for data abstraction, the address fetch operator requires that the operand be the left value, which forms a conflict, this conflict cannot be solved using the early definition of the Left value.
As a result, there is another idea about the left value. In this opinion, the left value should indicate a container (object). In layman's terms, it indicates a "hole", which can store things (numerical values) in this "hole ), of course, you can also modify the content in the "hole. This "hole" is indicated by a expression, which is called a left-value expression. In this definition, L in lvalue does not represent left, but locator; R in rvalue does not represent right, but read. These two changes indicate different meanings from the value assignment operator operands, that is, the left value is an object indicator, and the right value is the value read from this object. Some objects can be modified, and some objects cannot be modified. Correspondingly, there are modifiable left values and unchangeable left values.
The two different interpretations of the Left value are popular in the C community, and even lead to disputes in the C community. By the time the c89 standard was developed, the c89 Committee had made a compromise on the two ideas, using the locator definition as the definition of the Left value, the definition of the value assignment operator serves as the basis for determining whether the left value can be modified. c89 discussed this issue in rational:
6.3.2 other operands
6.3.2.1 lvalues, arrays, and function designators
A difference of opinion within the C Community centered around the meaningLvalue, One group considering an lvalue to be any kind of object locator, another group holding that an lvalue is meaningful on the left side of an Assigning
Operator. The c89 Committee adopted the definition of lvalue as an object locator. The termModifiable lvalueIs used for the second of the above concepts.
Therefore, in c89, the definition of the Left value is an expression indicating the object. This expression has the object type or non-void incomplete type, while the definition of the right value is the value of the expression. See the original c89 text:
6.2.2 other operands.
6.2.2.1 lvalues and function designators
An lvalue is an expression (with an object type or an incomplete type other than void) that designates an object :"
What is sometimes called "rvalue" is in this International Standard described as the "value of an expression ".
Later, various standard versions of c99 and C ++ used the main semantics of this definition and only modified some minor details. The comparison between the left value model and the early definition of the Left Value Model of C/C ++ is a huge improvement, which makes the left value no longer limited to the operation rules of an operator, it is extended to the object model, giving the left value an unprecedented rich connotation.
According to the C standard, whether the left value of an expression is irrelevant to whether it can be used as the left operand of the built-in value assignment operator depends on whether the expression has an object or non-void incomplete type, when we determine whether a left value can be modified, it can be modified based on whether it can be used as the left operand of the built-in value assignment operator, what is not allowed is the left value that cannot be modified.
C89 also specifies that the Left value must indicate a valid object. This is a mistake because some expressions, such:
Int * P;
* P = ......
Although P does not point to a valid object, the * P here is obviously still a left value. The definition of c89 ruled out this situation, which is not reasonable. This error was corrected in c99, c99 no longer specifies that the Left value must indicate a valid object, but indicates that if a left value that does not indicate a valid object is used, its behavior is undefined. C99 Original:
6.3.2 other operands
6.3.2.1 lvalues, arrays, and function designators
AnLvalueIs an expression with an object type or an incomplete type otherVoid; If an lvalue does not designate an object when it is evaluated, the behavior is undefined.
In C/C ++, a function-type expression is called a function indicator, for example, a function name or a reference to a function pointer. Since the left value in C reflects data abstraction rather than operation abstraction, the function indicator in C is neither the left value nor the right value, this concept is also embodied in the function-to-pointer conversion clause. The function-to-pointer conversion clause only indicates that the conversion result is a pointer, but does not indicate the left value of the result. In C ++, this concept has changed. c ++ believes that since the left value is the attribute of the expression, it is unreasonable that the function indicator as an elementary expression does not have the left value. In addition, given that the Left value of the function indicator is not harmful, therefore, the left value in C ++ also includes the function indicator. Note that the Left value of a function does not include non-static member functions, because the pointers of non-static member functions are very different from normal pointers, the C ++ standard emphasizes the difference between the two. It is hard to specify that the Left value of a non-static member function cannot be obtained, thus prohibiting the conversion of the Left value of a non-static member function.
C ++ defines the left value as follows: an expression is either the left value or the right value, which is completely different from C. At the beginning, it seems that this definition is very "sloppy". In fact, it is not the case. The specific reason is related to the type division method of C/C ++. The Type System in C/C ++ can have multiple partitioning methods, such as basic types and composite types (also called derived types), scalar types, and aggregation types, another type is divided into object type, incomplete type, function type, and reference type based on the object model (C has no reference type ), c ++ specifies that the reference type belongs to the left value and the function is also included in the left value category. Therefore, the left value of C ++ includes all types in the object model division method, using the left-value definition method similar to C is redundant. c ++ only needs to point out that the expression is neither the left value nor the right value, but C won't work, because C has an expression that is neither left nor right: function indicator!