5

I am answering a textbook question from this textbook.

I am learning about pointers in C and have come across l-values and r-values. From my understanding:

l-values are values that are defined after they are executed (++x)
r-values are values that are not defined after they are executed (x++)

It that correct?

The question I wanted to answer (with my attempts):

a) Which of the following C expressions are L-Values?
   1.  x + 2 Not a L value
   2.  &x    Is a L value
   3.  *&x   Is a L value
   4.  &x + 2  Not a L value
   5.  *(&x + 2) Is a L value
   6.  &*y  Is a L value

b) Is it possible for a C expression to be a L-value but NOT a R-value? Explain
   I've read that a L value can be a R value but not vice versa. I can't think of an example of something being an L value but not a R value.

c) Is &(&z) ever legal in C? Explain
   Assuming this is not legal since a memory address doesn't have its own memory address?

Am I close? Thanks

5
  • 3
    Why have you tagged this c++ ? Commented Sep 30, 2014 at 20:38
  • BTW although value categories in C and C++ have mostly the same end effect, they get there via very different paths. There won't be any explanations that apply to both. A question like this needs to pick one language. Commented Sep 30, 2014 at 20:42
  • @BenVoigt: I've deleted the C++ tag, since the OP says he's learning about C. Commented Sep 30, 2014 at 20:51
  • (a) R, R, L, R, L, R (b) No* (c) No Commented Sep 30, 2014 at 20:54
  • I've found the C FAQ entry to be very useful when explaining lvalues/rvalues. Commented Oct 1, 2014 at 7:00

1 Answer 1

16

l-values are values that are defined after they are executed (++x) r-values are values that are not defined after they are executed (x++)

No, that's not correct.

The words "lvalue" and "rvalue" (that's how the C standard spells them) have a long history. The terms come from 'l' for "left" and 'r' for "right", referring to the left and right sides of an assignment.

In some contexts, an expression may be either evaluated for its lvalue or evaluated for its rvalue. Given those definitions of the terms, an "rvalue" is what you'd normally think of as the value of an expression; evaluating 2+2 yields 4. Evaluating an expression for its lvalue meant determining what object it refers to. For example, given:

int x;
x = 2 + 2;

the right side of the assignment, 2 + 2 would be evaluated for its rvalue, yielding 4, and the left side would be evaluated for its lvalue, which means determining the object to which it refers. (The rvalue of the expression is not evaluated; the value previously stored in x, if any, is not used.)

The C standard defines them differently. In C, an lvalue is not a value; it's a kind of expression. Specifically, quoting the 2011 ISO C standard, section 6.3.2.1:

An lvalue is an expression (with an object type other than void) that potentially designates an object; if an lvalue does not designate an object when it is evaluated, the behavior is undefined.

(The word "potentially" was added to cover cases like *ptr, where ptr is a pointer object; if ptr == NULL then *ptr doesn't currently designate an object, but it's still an lvalue. You can always determine at compile time whether a given expression is an lvalue or not. Earlier editions of the C standard had flawed definitions for lvalue.)

So basically an lvalue in C is an expression that designates an object. You can think of it as an expression that can appear on the left side of an assignment, though that's not entirely accurate; for example, the name of a const object can't be on the LHS of an assignment, but it's still an lvalue. (As you can see, nailing down a precise and consistent definition for lvalue can be tricky.)

Neither x++ nor ++x is an lvalue in C.

The C standard doesn't use the term rvalue beyond mentioning it in a single footnote:

What is sometimes called "rvalue" is in this International Standard described as the "value of an expression".

So, as C defines the terms, an lvalue is a kind of expression (something that exists in C source code), but an rvalue is the result of evaluating an expression (something that exists during program execution).

(C++ has different rules, and several other classes of lvalue-like things, including glvalues and so forth. I won't get into that here.)

Sign up to request clarification or add additional context in comments.

5 Comments

The C standard does not spell rvalue (except in a footnote)
@AnttiHaapala: Yes, I said that in my answer.
@KeithThompson Thank you for your answer. I found it after coming across your post on another forum: thecodingforums.com/threads/writing-a-c-compiler-lvalues.722602/…. You mention there that the The distinction between computing the address of an object and "designating" an object is subtle but important. I think this might be what is causing my confusion and was wondering if you could please elaborate on it? I have posted my question here: stackoverflow.com/questions/78675822/…
@user135792 FYI, I did not post on thecodingforums.com. I posted on the comp.lang.c Usenet group, and thecodingforums.com grabbed and posted a copy.
@user135792 I've posted an answer to the linked question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.