1

I have to pieces of code:

int m = 4;
int result = 3 * (++m);

and

int m = 4;
int result = 3 * (m++);

After the execution m is 5 and result is 15 in the first case, but in the second case, m is also 5 but result is 12. Why is this the case? Shouldn't it be at least the same behaviour?

I'm specifically talking about the rules of precedence. I always thought that these rules state that parantheses have a higher precedence than unary operators. So why isn't the expression in the parantheses evaluated first?

4 Answers4

7

No - because in the first case the result is 3 multiplied by "the value of m after it's incremented" whereas in the second case the result is 3 multiplied by "the initial value of m before it's incremented".

This is the normal difference between pre-increment ("increment, and the value of the expression is the value after the increment") and post-increment ("remember the original value, then increment; the value of the expression is the original one").

Catfish
  • 18,876
  • 54
  • 209
  • 353
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thanks, but why do the rules of precedence not apply here? – RoflcoptrException Sep 20 '11 at 19:39
  • @Roflcoptr: What sort of precedence are you expecting to make a difference? It's the value of the pre/post-increment expression itself which is relevant. I don't see how precedence is relevant. – Jon Skeet Sep 20 '11 at 19:40
  • 1
    I thought the rules of precendence state that parentheses have a higher precedence than unary operators. Therefore the expression in the parantheses should be evaluated first. – RoflcoptrException Sep 20 '11 at 19:43
  • 2
    @Roflcoptr The fact that the expression in parantheses is evaluated first isn't relevant (or true, actually). The value of the expression `(m++)` is `m`, not `m + 1`. – dlev Sep 20 '11 at 19:46
  • @Roflcoptr: No, precedence doesn't change the evaluation order - it changes *grouping*. See http://blogs.msdn.com/b/ericlippert/archive/2008/05/23/precedence-vs-associativity-vs-order.aspx for Eric Lippert's well written blog post on this. The context is C#, but the same applies in Java. Even if this *did* affect evaluation order, it wouldn't change the result, given that the LHS of the multiplication doesn't use `m`. Why do you think it would? What would you expect the result to be, and why? – Jon Skeet Sep 20 '11 at 19:48
  • My expected result was 15 for both cases because I thought that first m is incremented in both cases since it is written in parentheses. But with your explanation it is a little bit clearer why this isn't the case. – RoflcoptrException Sep 20 '11 at 19:54
  • @Roflcoptr: Even if the RHS were evaluated first, the value of that expression would still be 4 for `m++`. So hopefully this question has helped you understand both precedence *and* pre/post-increment operators :) – Jon Skeet Sep 20 '11 at 19:55
  • IMHO, this kind of confusion is common enough to suggest that post-increment should be avoided, except perhaps as a standalone statement. – Ed Staub Sep 20 '11 at 19:59
  • @Ed: I rarely use *either* except as a standalone statement (where I always use the postincrement as I find it easier to read :) – Jon Skeet Sep 20 '11 at 20:00
  • Easier to read **and** makes for better rhyming in limericks. – corsiKa Sep 20 '11 at 20:05
3

The difference is when the result is assigned to m. In the first case you have basically (not what it really does, but helps to understand)...

int result = 3 * (m=m+1);

In the second case you have

int result = 3 * m; m = m +1;
Java Drinker
  • 3,127
  • 1
  • 21
  • 19
1

Think of it as "increment and get" and "get and increment." For instance, see AtomicInteger, which has the methods incrementAndGet() and getAndIncrement().

mrkhrts
  • 829
  • 7
  • 17
1

This is the definition of the operators: m++ evaluates to m, then increments m. It's a "post-increment". Parentheses around it don't change the fact that the operator evaluates to the variable, and also increments it afterward.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662