Velocity Reviews > lvalues and rvalues

# lvalues and rvalues

Stephen Sprunk
Guest
Posts: n/a

 04-07-2010
On 06 Apr 2010 16:38, Keith Thompson wrote:
> Given:
>
> int x = 42;
> int *ptr;
>
> the expressions ``x'' and` ``*ptr'' are both lvalues. ``x''
> unconditionally designates an object. ``*ptr'' may or may not
> designate an object, depending on the value currently stored in
> ptr; this is where the potential for undefined behavior comes in.

"ptr" also unconditionally designates an object. (I'm sure you knew
that; I just point it out for completeness.)

> I mentioned that the C standard doesn't use the traditional meanings
> of the terms. I'll summarize my understanding of what those
> traditional meanings are.
> ...
> An rvalue is just an ordinary value of
> some type. An lvalue is something that, rather than being a *value*
> of some type, identifies an *object* of some type. The traditional
> terminology unifies these two things (having a value vs. identifying
> an object) into the single concept of "value", divided into "rvalue"
> and "lvalue". The names of course come from the contexts in which
> they appear, the right side vs. the left side of an assignment.
>
> Note that some expressions, such as ``2 + 2'' cannot be evaluated for
> their lvalues. (In C terms, ``2 + 2'' is not an lvalue.)
>
> The authors of the C standard chose to drop the concept of "rvalue"
> (other than a brief mention in a footnote which matches the
> traditional meaning) and redefine "lvalue" as a kind of expression
> rather than as the result of evaluating such an expression.

Is dropping the term "rvalue" why the C Standard's definition of
"lvalue" is so tortuous--and continues to get even more so with each
revision as they try to correct problems with the prior one?

Digesting what you have said, this is how I mentally process the terms:

.. A modifiable lvalue is any expression which _could_ have a meaningful
result if it appeared on the LHS of an assignment.
.. A non-modifiable lvalue is any expression which _would_ be a
modifiable lvalue if it weren't const.
.. An rvalue is any expression which isn't an lvalue.
.. If an lvalue occurs in a context which does not require an lvalue, it
is evaluated to produce an rvalue.

Granted, that definitely isn't how the C Standard uses or defines the
terms, but aside from that, is it accurate enough for someone other than
a compiler author? Or is there some subtle flaw in there that will bite
me someday?

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking

Keith Thompson
Guest
Posts: n/a

 04-07-2010
Stephen Sprunk <(E-Mail Removed)> writes:
[...]
> Is dropping the term "rvalue" why the C Standard's definition of
> "lvalue" is so tortuous--and continues to get even more so with each
> revision as they try to correct problems with the prior one?

I don't think so. I think the problem is with "lvalue", not with
"rvalue". I find lvalues to be a more complicated concept anyway, for
either definition.

> Digesting what you have said, this is how I mentally process the terms:
>
> . A modifiable lvalue is any expression which _could_ have a meaningful
> result if it appeared on the LHS of an assignment.
> . A non-modifiable lvalue is any expression which _would_ be a
> modifiable lvalue if it weren't const.
> . An rvalue is any expression which isn't an lvalue.
> . If an lvalue occurs in a context which does not require an lvalue, it
> is evaluated to produce an rvalue.
>
> Granted, that definitely isn't how the C Standard uses or defines the
> terms, but aside from that, is it accurate enough for someone other than
> a compiler author? Or is there some subtle flaw in there that will bite
> me someday?

Your definition of "rvalue" directly contradicts the standard's
definition; an "rvalue" is not an expression, it's the result of
evaluating an expression.

I'd probably drop your third bullet and replace "rvalue" by "value" in
the fourth.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Phil Carmody
Guest
Posts: n/a

 04-07-2010
"bartc" <(E-Mail Removed)> writes:
> "Nicklas Karlsson" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> Hello,
>>
>> I am quite confused about this, so I split it in to subquestions, here
>> we go:
>>
>> 1. Is an lvalue the expression itself, or is it the result yielded by
>> evaluation of an expression? Take this for example: int i = 10; int *p
>> = &i; and then dereference: *p; is the expression "*p" the thing you
>> call an lvalue or is an lvalue the result yielded by evaluating that
>> lvalue-expression?

>
> A rule of thumb might be: if you can apply the & operator to it
> (address-of), then it can be an lvalue (with a few exceptions such as
> function names)
>
> But here:
>
> int A,B;
>
> A = B;
>
> Both A,B could be lvalues, but only A is being used as one. (In assembly,
> you will find little difference between how the two are treated:
>
> mov [A],[B] # assuming memory-to-memory allowed
>
> (I'm done a bit of compiler work; I would handle the assignment above as
> follows:
>
> *(&A) = B;

So you'd not want your variables in registers? Why on earth not?

Phil
--
I find the easiest thing to do is to k/f myself and just troll away
-- David Melville on r.a.s.f1

Stefan Ram
Guest
Posts: n/a

 04-07-2010
Nicklas Karlsson <(E-Mail Removed)> writes:
>1. Is an lvalue the expression itself, or is it the result yielded by

An lvalue is an expression.

>2. Rvalues, is rvalues the result yielded by an rvalue-expression, or
>is it the expression itself? If its the result yielded by evaluation
>of an rvalue-expression is an rvalue a plain value?

An rvalue is the value of an expression (the value of the
expression except when it is the operand of the sizeof
operator, the unary & operator, the ++ operator, the --
operator, or the left operand of the . operator or an
assignment operator [possibly parenthesized]).

>the example of *p, the lvalue will be of type "int", if an lvalue-
>expression always yields an address when evaluated, C could keep track

An lvalue designates an object, it does not have to
have a pointer type.

Stefan Ram
Guest
Posts: n/a

 04-07-2010
http://www.velocityreviews.com/forums/(E-Mail Removed)-berlin.de (Stefan Ram) writes:
>An lvalue is an expression.

Having read parts of the discussion:

I'd put it in these words, if I was invited to write a
specification for the language C:

Every expression might designate an object and/or a
value. (For the definition of the object and the value,
see the chapter "expressions", where this is specified
for each type of expression.)

Every operator can require each of its operands to
designate an object and/or a value. (See the chapter
"expressions", where this is specified for each
operator.)

For example, the assignment operator »=« requires its
left operand to designate an object and its right
operand to designate a value. It then writes this value
into that object.

Keith Thompson
Guest
Posts: n/a

 04-07-2010
(E-Mail Removed)-berlin.de (Stefan Ram) writes:
> (E-Mail Removed)-berlin.de (Stefan Ram) writes:
>>An lvalue is an expression.

>
> Having read parts of the discussion:
>
> I'd put it in these words, if I was invited to write a
> specification for the language C:
>
> Every expression might designate an object and/or a
> value. (For the definition of the object and the value,
> see the chapter "expressions", where this is specified
> for each type of expression.)
>
> Every operator can require each of its operands to
> designate an object and/or a value. (See the chapter
> "expressions", where this is specified for each
> operator.)
>
> For example, the assignment operator Â»=Â« requires its
> left operand to designate an object and its right
> operand to designate a value. It then writes this value
> into that object.

Clarification: All expressions designate values; only some expressions
designate objects.

And of course some expressions that are lvalues may not designate
objects depending on the values of certain subexpresions; ``*ptr''
designates an object if and only if ptr happens to contain a valid

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

lawrence.jones@siemens.com
Guest
Posts: n/a

 04-07-2010
Keith Thompson <(E-Mail Removed)> wrote:
>
> What the standard probably should say is "if an lvalue does not
> designate an object when it is evaluated *in a context that requires
> an lvalue*, the behavior is undefined.

Isn't that addition redundant? I can't think of *any* context where an
lvalue that doesn't desginate an object can be safely evaluated.
--
Larry Jones

I'm a genius. -- Calvin

lawrence.jones@siemens.com
Guest
Posts: n/a

 04-07-2010
Stephen Sprunk <(E-Mail Removed)> wrote:
>
> . A non-modifiable lvalue is any expression which _would_ be a
> modifiable lvalue if it weren't const.

An array is a non-modifiable lvalue but is not const (only the elements
can be const in C, not the array itself).
--
Larry Jones

I don't want to be THIS good! -- Calvin

Nicklas Karlsson
Guest
Posts: n/a

 04-07-2010
Let me summarize what I make of this (hopefully its correct):

What is an lvalue?
An expression that designates (identifies) an object, when evaluated
the compiler knows what object is being designated and what type that
object has.

What is an rvalue?
The result of an expression that is not an lvalue appearing in LHS (an
lvalue, when evaluated, yields an rvalue if it appears on RHS, that
is, the value of the object being designated is being fetched, however
if its on LHS it does not evaluate to an rvalue but rather evaluates
so the compiler knows where to store an rvalue, that is, it identifies
an object and what type that object has).

What is an object?
A region of data storage, usally an object is a place in memory, so it
usally has a starting address, but it could also be stored in other
ways, for example in the CPU's register and therefor won't have an

Silly question, the lvalue (expression) itself has no type right? But
when its evaluated the compiler finds out what type the object that
the lvalue identifies has?

Keith Thompson
Guest
Posts: n/a

 04-07-2010
Nicklas Karlsson <(E-Mail Removed)> writes:
> Let me summarize what I make of this (hopefully its correct):
>
> What is an lvalue?
> An expression that designates (identifies) an object, when evaluated
> the compiler knows what object is being designated and what type that
> object has.

Close. Evaluation happens at run time; the compiler doesn't
necessarily know which object is being designated. It does know
the type of the object -- or rather the type imposed by the lvalue.
This might not be the declared type of the object itself. In fact,
the object might not even have a declared type.

Some examples (I haven't taken the time to test these):

int x, y, *ptr;
switch (rand() % 3) {
case 0: ptr = NULL; break;
case 1: ptr = &x; break;
case 2: ptr = &y; break;
}
*ptr; /* an lvalue, but the compiler has no idea whether it
designates x, y, or no object at all */

void *vptr = malloc(sizeof(int));
assert(vptr != NULL);
/* We've just created an object, but it has no inherent type. */
*(int*)vptr; /* the type is imposed by the lvalue */
*(unsigned*)vptr; /* same object, different lvalue, different type */

> What is an rvalue?
> The result of an expression that is not an lvalue appearing in LHS (an
> lvalue, when evaluated, yields an rvalue if it appears on RHS, that
> is, the value of the object being designated is being fetched, however
> if its on LHS it does not evaluate to an rvalue but rather evaluates
> so the compiler knows where to store an rvalue, that is, it identifies
> an object and what type that object has).

Too many words. An rvalue is the value of an expression, that's all.
It's also a term that the Standard doesn't use, and I see little point
in using it while discussing C. <OT>(C++ is another matter.)</OT>

> What is an object?
> A region of data storage, usally an object is a place in memory, so it
> usally has a starting address, but it could also be stored in other
> ways, for example in the CPU's register and therefor won't have an

I'd say "address" rather than "starting address". In C, an address is
typed. It doesn't point to the beginning of an object, it points to
the object.

> Silly question, the lvalue (expression) itself has no type right? But
> when its evaluated the compiler finds out what type the object that
> the lvalue identifies has?

No, an lvalue, like any expression, has a type.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"