The rvalue definition is an object that cannot be assigned a value, but why are lvalues ​​literals?

So, I look at our extended upcoming topics, and I come to lvalues ​​and rvalues, although the definition confuses me. Why is it literally an lvalue?

"rvalue refers to a data value that is stored at any address in memory. rvalue is an expression that cannot have a value assigned to it"

“The original definition of lvalue refers to“ an object that may appear on the left side of the job. ”However, const objects are lvalues, and yet they cannot appear on the left side of the job.”

+4
source share
3 answers

C: const objects have three categories of untranslatable values: arrays (and objects with elements that are a constant or an array) and expressions with an incomplete type.

String literals are arrays (by which I mean: the object to which the string literal expression refers is an array). This makes them lvalues.

Unofficially, lvalue is an expression that refers to an object, and a string literal is an object.


If you want a formal definition of lvalue in C, refer to the standard. In C99 (6.3.2.1):

lvalue is an expression with an object type or an incomplete type other than void; if lvalue does not indicate an object when evaluating it, the behavior is undefined.

with a footnote:

The name '' lvalue comes originally from the assignment expression E1 = E2, in which the left operand E1 must be a (mutable) value of l. Perhaps this is best seen as an object. '' Locator value

Thus, the appearance on LHS of an assignment has nothing to do with it, except that lvalue meant something else, in some other language than standard C.

You might think that with this formal definition the integer constant 5 should also be an lvalue expression: it is an expression (in particular, a primary expression) and has an object type ( int is an object type). This is certainly true for evaluating expression 5 , so if it is an lvalue, then it should "denote an object."

This would contradict the definition of the address operator, which states that its operand may be an lvalue expression that denotes an object. Compilers reject &5 , usually with an error message indicating that 5 not an lvalue.

I think the answer lies in 6.5.1, which lists various types of primary expression, including constants. For each of the other types of primary expression, he says under what conditions this value is. For constants, he says nothing, indicating that they are not lvalues. But, as a rule, in the C standard, the text of the form "An X is ...", using italics X, is the definition of the term X. Therefore, I believe that the standard can be clearer.

Update: text in n1570 (late draft C11), with the addition of my attention:

lvalue is an expression (with an object type other than void) that potentially denotes an object

And the equivalent text in C89 (3.2.2.1) says that "designates an object" [thanks hvd]. This suggests that the authors of the standard are also unhappy with the text. A constant does not potentially denote an object, therefore, in this definition, numerical constants are, of course, not lvalues.

+4
source

The informal definition of lvalue is basically any expression that can refer to an object (in the sense of C, everything that takes up memory), so that the value of the object can be read or changed. All you could use the unary & operator is an lvalue.

Unfortunately, you have some expressions that can refer to objects in memory, but the semantics are such that you cannot change this value of an object through this expression. This includes array expressions (including string literals), const -qualified type expressions, and partial type expressions.

An example of the latter type looks something like this:

 struct foo; struct foo *fooptr; 

The expression *fooptr is an expression with an incomplete type; struct foo is not yet fully defined.

Thus, we have modifiable and unmodifiable values ​​of l. The modifiable value of lvalue may be the target of an assignment.

String literals are unmodifiable lvalues ​​due to array type expressions (string literals are stored as char arrays, so that the memory is visible to the entire program and is kept from running the program until completion, and the semantics of arrays are such that array expressions may not be the purpose of the assignment) . This is a different situation from numeric literals or individual character constants that do not apply to elements in memory.

+1
source

rvalues ​​are defined as things that do not have a name or that you cannot use for addresses or temporary.

The original definition is no longer valid these days. You can take the address of lvalues, but not rvalues, which for me is the simplest difference.

If you can’t get its address, then it will be an rvalue.

0
source

Source: https://habr.com/ru/post/1432994/


All Articles