3

Why does that code does not compile due to an error:

#include <iostream>

using namespace std;

int main()
{
    int i = 0; 
    cout << ++(i++) << " " << i << endl;
    return 0;
}

While that code does compile:

#include <iostream>

using namespace std;

int main()
{
    int i = 0; 
    cout << (++i)++ << " " << i << endl;
    return 0;
}

I do not understand that. From my point of view it would be pretty reasonable for the first chunk to compile. The expression ++(i++) would just mean take i, increment it and output, then increment it again.

I am not asking about an undefined behavior in int overflow. I do not know about r and l value at all at the time of writing the question and I do not care why is ++i considered an l-value, but i++ is not.

Paul Roub
  • 36,322
  • 27
  • 84
  • 93
Yaroslav
  • 1,325
  • 1
  • 11
  • 23
  • 3
    Possible duplicate of [Why is ++i considered an l-value, but i++ is not?](https://stackoverflow.com/questions/371503/why-is-i-considered-an-l-value-but-i-is-not) – Eugene Sh. Jul 07 '17 at 18:22
  • @user0042, I looked up the answer and it did not helm me out. I do not asking about integer overflow and there is no undefined behavior in my code, there is just an error. – Yaroslav Jul 07 '17 at 18:23
  • @EugeneSh., did you read my question at all? It is totally different from the one you are proposing to be a duplicate. – Yaroslav Jul 07 '17 at 18:24
  • 2
    @Yaroslav It is the exact question. Post and pre-increment operators require `lvalue` as an operand. In your question the first one is not an `lvalue`, but the second is. – Eugene Sh. Jul 07 '17 at 18:25
  • http://en.cppreference.com/w/cpp/language/operator_precedence – Jesper Juhl Jul 07 '17 at 18:27
  • 1
    @EugeneSh., okay. Now you give me an answer. But how am I supposed to know the answer while asking the question? It is just turned out that the answer to the question you are proposing to be the duplicate of mine helps to give an answer to my question. – Yaroslav Jul 07 '17 at 18:27
  • @Yaroslav Well, you are asking about the consequence, but that question is about the cause. There are numerous consequences of the same cause. If it is not always obvious, the comments are here. Anyway, you have got your answer, right? – Eugene Sh. Jul 07 '17 at 18:29
  • @EugeneSh., yep I did. Thanks for the attention. – Yaroslav Jul 07 '17 at 18:30
  • @Yaroslav _"But how am I supposed to know the answer while asking the question?"_ You aren't. Duplicates aren't an inherently bad thing, but improve the SO network. – user0042 Jul 07 '17 at 18:39
  • @user0042, got it. – Yaroslav Jul 07 '17 at 18:44

3 Answers3

8

This is because the post increment and pre increment operators return values with different types. Result of post increment is a so-called 'rvalue', meaning it can not be modified. But pre-increment needs a modifiable value to increment it!

On the other hand, result of pre-increment is an lvalue, meaning that it can be safely modified by the post increment.

And the reason for above rules is the fact that post-increment needs to return a value of the object as it was before increment was applied. By the way, this is why in general case post-incrememts are considered to be more expensive than pre-increments when used on non-builtin objects.

Rakete1111
  • 47,013
  • 16
  • 123
  • 162
SergeyA
  • 61,605
  • 5
  • 78
  • 137
2

Shortly speaking the difference is that in C++ you may use any even number of pluses (restricted only by the compiler limits) for the prefix increment operator like this

++++++++++++++++i;

and only two pluses for the post increment operator

i++;

The postfix increment operator returns a value (The C++ Standard, 5.2.6 Increment and decrement)

1 The value of a postfix ++ expression is the value of its operand. [ Note: the value obtained is a copy of the original value —end note ]

While the prefix increment operator returns its operand after increment (The C++ Standard ,5.3.2 Increment and decrement)

1 ...The result is the updated operand; it is an lvalue...

Opposite to C++ in C you also can apply only two pluses to an object using the prefix increment operator.:) Thus the C compiler will issue an error for such an expression like this

++++++++++++++++i;
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

When you compile it with clang you get error message that says it all.

<source>:8:13: error: expression is not assignable
cout << ++(i++) << " " << i << endl;

Maybe it is good to start with ++ operator. In fact it is shorthand for i = i + 1. Now if we look at postfix version i++, it says in standard that it returns copy of original value and as side efect it increments original value. So from (i++) you get rvalue and are trying to assign to it and as we know you can't assign to rvalue.

Marek Vitek
  • 1,573
  • 9
  • 20