0

In below code:

main()
{
  int i = 5;
  printf("%d", ++i++);
}

This Program is giving the error "L-Value required".

Can some one tell me : Why compilation error?

Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
vinod kumar
  • 175
  • 2
  • 3
  • 6
  • Is that the only thing in the code? – Kneel-Before-ZOD Jul 25 '13 at 06:47
  • 1
    Wonder how the first C programs in the world happen to be so esoteric! – devnull Jul 25 '13 at 06:47
  • @Kneel-Before-ZOD OP question is why its l-value error, that is a good question to understand. – Grijesh Chauhan Jul 25 '13 at 06:51
  • 1
    A C99 or C11 compiler complains about no return type on the function `main()` — it should return `int`; it also complains about no declaration of the function `printf()` — which is doubly crucial since it is a 'varargs' function so invoking it without a prototype in scope leads to undefined behaviour; and finally it complains about the illegal expression `++i++`. And only in C99 or C11 is it legal not to return a value from `main()`; prior to that, you needed `return 0;` before the end. – Jonathan Leffler Jul 25 '13 at 06:54
  • @GrijeshChauhan Which is why I asked the question. The code is incomplete. The function declaration is incomplete. And it has no return value. – Kneel-Before-ZOD Jul 25 '13 at 06:56
  • 1
    Nothing undefined here, it's a syntax error. – Lee Daniel Crocker Jul 25 '13 at 07:02
  • @LeeDanielCrocker yes its not undefined but conceptually its undefined behavior to doing like this. thats what I wrote this – Grijesh Chauhan Jul 25 '13 at 07:40
  • 1
    @PHIfounder No this question doesn't duplicates with linked code! yes that code compiles with every compiler --result of which is Undefined, While this question is about Compilation error. There `++` applied on **variable** here `++` applied on **expression**. It doesn't duplicates – Grijesh Chauhan Jul 25 '13 at 22:11
  • 3
    Why users marking it duplicate with the linked question whereas its not. – Grijesh Chauhan Jul 25 '13 at 22:12
  • @GrijeshChauhan Yeah, I got that minute difference by the discussion going on , on this topic but anyway :) – 0decimal0 Jul 26 '13 at 01:58
  • 1
    Voted to reopen, the duplicate is incorrect. – jrok Aug 15 '13 at 18:09
  • @JonathanLeffler; Why you marked it as duplicate? I am not agree. – haccks Aug 15 '13 at 18:24
  • @haccks: I'm not the person who currently has the distinction of closing it as a duplicate. If I previously tagged it as closable/duplicate, it is because the other question is also about `++i++` and I find it hard to believe that there is much to be said about it here that wasn't said there -- but I have not looked again now to validate that assumption. – Jonathan Leffler Aug 15 '13 at 23:13
  • @JonathanLeffler; I think `++i++` doesn't invoke UB unlike that [question](http://stackoverflow.com/questions/949433/could-anyone-explain-these-undefined-behaviors-i-i-i-i-i-etc) and it is completely a different issue. – haccks Aug 16 '13 at 05:03
  • @haccks: You're right that `++i++` doesn't invoke UB; it is an outright violation of the rules of C (it is defined to be invalid) and completely inadmissible as an expression. It looks completely parallel to the duplicate question. The 'close as duplicate' is reasonable in my view. – Jonathan Leffler Aug 16 '13 at 13:05

5 Answers5

7

Because postfix operators have higher precedence than prefix operators, so the expression ++i++ is equivalent to ++(i++), that is equivalent to ++( i + 1). The compiler gives l-value error because you are applying ++ on an expression (i++) that is not a modifiable lvalue, so not a valid expression in according to increment operator definition.

According to Dennis M. Ritchie's book: "The C Programming Language":

2.8 Increment and Decrement Operators

(page 44)

The increment and decrement operators can only be applied to variables; an expression like (i + j)++ is illegal. The operand must be a modifiable lvalue of arithmetic or pointer type.

Related: An interesting bug one may like to know about in gcc 4.4.5 is that expression j = ++(i | i); compiles that should produce l-value error. Read: j = ++(i | i); and j = ++(i & i); should an error: lvalue?

Additionally, modifying same variable more then once in an expression without an intervening sequence point causes which is undefined behavior in and . To understand read Explain these undefined behaviors in i = i++ + ++i;.

Community
  • 1
  • 1
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
  • 2
    I don't see how you can claim "undefined behavior because `i` is modified twice without a sequence point" and in the same breath explain that `i` is modified once. – This isn't my real name Jul 25 '13 at 06:52
  • 4
    Actually, postfix operators have higher precedence than prefix operators, so the `i+++` would be done first, but since the result of `i++` is an r-value and not an l-value and prefix `++` can only be applied to an l-value, the error message is given. That's a problem before you get to the undefined behaviour of modifying a single variable more than once in an expression. – Jonathan Leffler Jul 25 '13 at 06:52
  • @JonathanLeffler `postfix operators have higher precedence than prefix operators` ? no prefix evaluates first I think? – Grijesh Chauhan Jul 25 '13 at 06:56
  • 2
    Go and look at the standard. The operators are presented in order of precedence (high to low), and §6.5.2 **Postfix operators** comes before §6.5.3 **Unary operators**. (And I see I invented a new operator `i+++`; I meant `i++`!) – Jonathan Leffler Jul 25 '13 at 06:58
  • @JonathanLeffler So I should correct: `++i++` == as `++(i++)` == `++ ( 1 + 1)` Thanks I just saw Its very rare case so I confuse – Grijesh Chauhan Jul 25 '13 at 07:00
  • 1
    Better. Of course, since I'm nicking pits, the result of `i++` is the old value of `i`, so it is more like: `++(i+=1, i-1)`, but since the whole thing is illegal, this whole debate is a little like the great questions of how many angels can dance on the head of a pin (and the answer to that does not appear to be 42, even though 42 is The Answer to The Question of Life, the Universe, and Everything). – Jonathan Leffler Jul 25 '13 at 07:04
1

Generally, you should not be doing this, as it obscures the code.
The reason you're getting the error is that the post-increment has precedent and thus returns an r-value, i.e. ++i++ == ++(i++) which cannot be incremented.

However, you can use (++i)++ since the pre-increment (apparently, on VS2010) returns i itself, an l-value which can be post-incremented.

Adi Shavit
  • 16,743
  • 5
  • 67
  • 137
0

this line:

printf("%d",++i++)

==>

printf("%d",(++i)++)

And

==>

 printf("%d",(++i)); &(++i)++ ==> (++i) = (++i) +1;

See you use (++i) as a left value.

Lidong Guo
  • 2,817
  • 2
  • 19
  • 31
0

This is because you are doing increment to a constant..

In your case

++i => 6
++i++ => 6++ //this is not possible. Gives lvalue error
++i+10 => 6+10 => 16 //this is possible

So doing ++i++ is not good. Post increment/decrement, pre increment/decrement possible only on variables. At runtime your statement will become a constant so it gives lvalue error here.

++i => 6 => i=6;
i++ => 6 => i=7;
printf("%d",i); //7
Amarnath Krishnan
  • 1,253
  • 1
  • 9
  • 12
0

The expression ++i++ is evaluated as ++(i++) which is illegal in C as the postfix increment returns a value and prefix incrementing on a that value makes no sense.

What you have is somewhat equivalent to: ++(5) which is obviously illegal as you can apply prefix increment on something that's not a l-value.

P.P
  • 117,907
  • 20
  • 175
  • 238