27

While playing around with the ++ operator, I tried to write the following:

++i++;

I expected this to compile at first, but I got a compiler error:

The operand of an increment or decrement operator must be a variable, property or indexer.

I then tried writing ++(i++) to help the compiler understand what I meant but it also (unsurprisingly) didn't work.

So I am left wondering what does the ++ operator return ? With the compiler error I am getting I was expecting ++i to not return an int representing the value of i incremented, but that is also not the case since I can do i = (++i) + 1 with success...

Anybody have any idea why the ++ operator cannot be chained ?

Also, (++i).GetType() does return System.Int32.

Humayun Shabbir
  • 2,961
  • 4
  • 20
  • 33
Bun
  • 1,465
  • 10
  • 23
  • You should look into C++ Operator overloading maybe it will clear things up http://stackoverflow.com/questions/4421706/operator-overloading – DotNetRussell Jul 23 '14 at 18:29
  • Just curious, does (++i)++ compile? I don't have VS in front of me, so I can't check. – RLH Jul 23 '14 at 18:44
  • No it doesn't. Because `++i` returns the value of `i` incremented and not the variable itself. (From what I just learnt :P) – Bun Jul 23 '14 at 18:45
  • 3
    `++i++;` does not mean anything and so it shouldn't compile. Remove your cat from the keyboard and move on. – H H Jul 23 '14 at 18:52
  • 4
    Much of your question is a duplicate of http://stackoverflow.com/questions/1511082/why-cant-i-do-i-in-c-like-languages/1511209#1511209. See also http://stackoverflow.com/questions/3346450/what-is-the-difference-between-i-and-i/3346729#3346729 and http://blog.coverity.com/2013/09/24/increment-semantics/ – Eric Lippert Jul 23 '14 at 20:32

4 Answers4

45

In C# The ++ operator returns the value before (for i++) or after (for ++i) incrementing.

The error you're seeing is because that operator can ONLY be used on a variable, property, or indexer. The reason is because the intent of the operator is to increment the variable that is being referenced. You can't use it on an expression or other type. What would (9++) do?

You expect (i++)++ to be equivalent to i++; i++. But i++ returns a value and internally increments i. Since you can't apply the ++ operator to a value chaining is not possible.

The difference in C++ is that the ++ prefix operator takes a reference as an input, and returns a reference to the original value, so you can chain the operator since it's just using the pointer instead of a value. The postfix operator returns a value and thus cannot be chained.

D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • That part about the C#/C++ comparison is very interesting (not that the rest of the answer isn't), and probably the source of my misunderstanding. Thanks very much. – Bun Jul 23 '14 at 18:38
  • 3
    Also covered by this [much more extensive answer by Eric Lippert](http://stackoverflow.com/a/3346729/60761) – H H Jul 23 '14 at 18:50
17

The result of the ++ or -- operator is the value of the variable, property, or indexer, and not the variable, property, or indexer itself.

You can't double-increment a variable like (i++)++ for the same reason you can't increment a value by itself like 100++.

p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
  • Wow I can't believe I didn't think of that. Thank you very much for the clear explanation. – Bun Jul 23 '14 at 18:35
4

If I can borrow terminology from C or C++, the ++ operator here returns an "r-value". An r-value doesn't map to a language type, it's a syntactical trick to distinguish what's assignable (modifiable) and what isn't.

Something that you can find on the left side of an assignment operation is called an l-value (left value), and things that you can find on the right side of an assignment are "r-values" (right values). The ++ operator has to operate on an l-value, because it needs to assign to it. However, the returned expression has to be an r-value, because it wouldn't make sense to do i++ = 4 in C#, just like it wouldn't make sense to do foo.Bar() = 4 or 1 = 5.

C# doesn't have lvalues or rvalues per se, but it limits what can be found on the left side of an assignment to variables, properties and indexer operations. This is, not coincidentally, also what you can use the ++ operator on.

zneak
  • 134,922
  • 42
  • 253
  • 328
  • 1
    Good answer. I note that you are correct to say that C# does not use the somewhat confusing "rvalue" / "lvalue" terminology. Rather, C# classifies all expressions into one of: *value, variable, namespace, type, method group, null literal, anonymous function, property, indexer, event and void-returning method call*. (Array initializers, though they look like expressions, are technically not expressions.) – Eric Lippert Jul 23 '14 at 20:37
1

I realized that you cannot use ++ before or after an expression.

When you use:

++(i++);

you are doing something like:

++(<expression>)

The compiler resolve the expression first and then it will increment the result of the expression and that sound crazy. The operand ++ works by increment an immediate variable no the result of an expression.

How the programming expressions are evaluated? The grammar of the Language (BNF) http://people.cis.ksu.edu/~schmidt/301s11/Lectures/bnfT.html

Here another example of the correct use of this operand ++

int i = 0, j = 0;
int sum = i++ + j++;
//result sum = 0, i = 1, j = 1

This operand ++ is messy, since do 3 thing at once (read, increment, assignment). I personally don't uses in large expressions, such as the example above: i++ + j++. But I still use it in the for-loop or while-loop by itself.

Even a short expression such as i = j++; is a mess. Keep your code simple and easy to understand. The same expression can be write like:

i = j;
j++; //or j+=1;
Jaider
  • 14,268
  • 5
  • 75
  • 82