6

I understand a few things about Lvalue but I don't understand how the below code gives an error:

#include<stdio.h>

void foo(int *);

int main() 
{
   int i=10;
   foo((&i)++);
}

void foo(int *p)
{
    printf("%d",*p);
}

6:13: error: lvalue required as increment operand foo((&i)++); ^

Amadeus
  • 9,558
  • 3
  • 24
  • 31
likeicare
  • 79
  • 9
  • 3
    Because `&i` is not an *lvalue*, and the `++` operator requires one. It's roughly equivalent to `&i = &i + 1;`, does the last expression makes sense to you? – Iharob Al Asimi Nov 11 '17 at 02:11
  • 1
    The variable `i` when used is an lvalue. If you had a pointer like `int *p = &i;` then `p` would be an lvalue too. But `&i` itself is *not* an lvalue. Perhaps you would be interested in [this value category reference](http://en.cppreference.com/w/c/language/value_category)? Note how [the list of non-lvalue expressions](http://en.cppreference.com/w/c/language/value_category#Non-lvalue_object_expressions) includes "the address-of operator". – Some programmer dude Nov 11 '17 at 02:12
  • Possible duplicate of [lvalue required as increment operand](https://stackoverflow.com/questions/3364445/lvalue-required-as-increment-operand) – ssharma Nov 11 '17 at 02:14
  • 1
    @IharobAlAsimi: Re: “…does the last expression [`&i = &i + 1;`] make sense to you?” Sure, I think it moves `i` one location further up in memory. – Eric Postpischil Nov 11 '17 at 04:04
  • @Some programmer dude: Is there a way(maybe a short trick) to remember what is lvalue and what is not?! – likeicare Nov 12 '17 at 06:37
  • The rule of thumb is, if you can apply the address-of operator `&` to something, then it's an lvalue. – Some programmer dude Nov 12 '17 at 06:45

2 Answers2

2

x++ results following steps.

1) read the value of x in to register.
2) increment the value of x
3) write the incremented value back to x (which means you are changing the value of x by '1')

But what you are trying to do is (&i)++ which means the following.

1) read address of i into register
2) increment the address by 1
3) write the incremented value in to address again? How you can change the address?

If you want to send the integer which is stored in next address to foo(), you need to increment as below.

int *p = &i + 1;
foo(p);

But that may result in undefined behavior because you know only address of i where i value is stored. Once you increment the address, you will get next address and it may contain some junk value.

kadina
  • 4,512
  • 3
  • 37
  • 72
1

There is an attempt to apply the unary operator & to a temporary object that is evaluated as the expression (&i)++. You may not apply the operator to a temporary object.

C Standard (6.5.3.2 Address and indirection operators):

1 The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.

msc
  • 32,079
  • 22
  • 110
  • 197
  • 1
    "*There is an attempt to apply the unary operator `&` to a temporary object ...*" sure? `&` is applied to `i`. To me it looks as if you mix up `&` and `++`. – alk Nov 11 '17 at 08:27