tez
tez

Reputation: 5300

Condition for lvalues and rvalues in C

Here are the few definitions I read about lvalues

  1. Expressions which can be used with & operator. i.e if &(expression) is not an error, then the expression is an lvalue

  2. Expression which results in objects that are not temporary

  3. lvalue expressions can be used on both RHS and LHS of = operator

  4. rvalue expressions can be used only on RHS

Please correct if wrong

Here's the question

I read ++x is a lvalue and x++ is an rvalue

int i = 0;
printf("%p",(void*)&++i);

If so, why is this an error?

If lvalue expressions can be used on lhs

int i = 0;
++i = 10;

Why can't I use the above statement??Both the above are resulting in errors

Update: Both the above statements are fine in C++

Upvotes: 3

Views: 528

Answers (5)

zakinster
zakinster

Reputation: 10688

++i is an lvalue only in C++, in C it's an rvalue (called value of an expression in the C standard) which cannot be assigned.

Upvotes: 3

Lundin
Lundin

Reputation: 213678

The (rather vague) formal definition from C11:

(emphasis in bold font was added by me)

6.3.2.1 Lvalues, arrays, and function designators

An lvalue is an expression (with an object type other than void) that potentially designates an object (64); if an lvalue does not designate an object when it is evaluated, the behavior is undefined. When an object is said to have a particular type, the type is specified by the lvalue used to designate the object. A modifiable lvalue is an lvalue that does not have array type, does not have an incomplete type, does not have a const-qualified type, and if it is a structure or union, does not have any member (including, recursively, any member or element of all contained aggregates or unions) with a const-qualified type.

Foot note (not normative) with further explanation:

64) The name "lvalue" comes originally from the assignment expression E1 = E2, in which the left operand E1 is required to be a (modifiable) lvalue. It is perhaps better considered as representing an object "locator value". What is sometimes called "rvalue" is in this International Standard described as the "value of an expression".

So an lvalue must be something that "potentially" designates an object. Whatever "potentially" means is open for personal interpretation...

Despite the above foot note, the C standard lacks a formal definition of a rvalue. Ironically, the only place in the whole standard mentioning rvalue is that one foot note.

In your case, neither ++i nor i++ designates an actual object, so neither of them are lvalues. They are rather rvalues.

Upvotes: 1

Dariusz
Dariusz

Reputation: 22241

I thought that this question would be closed, and I only left a comment. What a big mistake;)

In C (the question's tag is C) ++i operator does "return" a value, but not the variable itself. Hence it's address can not be retrieved. In other words ++i is not an lvalue. Neither is i++.

C++ is may be different from C in regard of certain constructs being l- and r-values.

http://eli.thegreenplace.net/2011/12/15/understanding-lvalues-and-rvalues-in-c-and-c/

For C++ these two are lvalues.

This simple code:

#include <stdio.h>

int main() {
  int i=0;
  ++i = 10;
  printf("\n%d\n", i);
  ++i = ++i;
  printf("%d\n", i);
}

Compiled with gcc will give:

lvalue.c:3: error: invalid lvalue in assignment
lvalue.c:4: warning: incompatible implicit declaration of built-in function ‘printf’
lvalue.c:5: error: invalid lvalue in assignment

and for g++ compiles correctly and yelds:

10
12

Upvotes: 2

Art
Art

Reputation: 20392

Neither ++i nor i++ are lvalues.

You might be thinking about *x++ and *++x which are both lvalues (if x has a pointer type).

Upvotes: 4

Gui13
Gui13

Reputation: 13541

By making ++i an lvalue, imagine that you can now do:

int i=2;
++i = ++i;

Apart from nasal daemons, what would you like i to look like afterwards? 4? 3?

Upvotes: 0

Related Questions