7

(Note: I came across this somewhat accidentally, so it may not be practical, but I am just very curious)

I wanted to print out a value, which was the sum of two values, after incrementing the second. Something like so:

int first = 10;
int second = 20;
System.out.println(first + ++second);  //31
System.out.println(first);             //10
System.out.println(second);            //21

Maybe not the neatest code, but it worked. But then, I started experimenting.

System.out.println(first +++ second);  //30
System.out.println(first);             //11
System.out.println(second);            //21

That's fine; it means that the first was incremented after being added, and that whitespace can be ignored here. Cool. But then...

System.out.println(first +++++ second);  //"Invalid Argument", doesn't work

While

System.out.println(first ++ + ++ second);  //31
System.out.println(first);             //11
System.out.println(second);            //21

Works fine, but for some reason, is still different than

System.out.println(first + + + ++ second);  //31
System.out.println(first);             //10
System.out.println(second);            //21

And maybe the strangest of all,

System.out.println(first + + + + + + second);  //30
System.out.println(first);             //10
System.out.println(second);            //20

So what's going on here? When is whitespace between operators ignored, and when is it not? Why can I write "+ + + + +", without any issues?

Thanks!

Sherz
  • 568
  • 2
  • 14

3 Answers3

11

This comes down to operator precedence. The order of operations goes:

  • postfix (foo++, foo--)
  • unary (++foo, --foo, +expr, ...)
  • ...
  • additive (+, -)
  • ...

So, let's take a look at each expression:

first + ++second is first + (++second). That's fine.

first +++ second is (first++) + second, which works as you said it does.

first +++++ second is ((first ++)++)+ second), but (first ++) is a value (not a variable) and thus can't be incremented -- that's what the error is trying to tell you.

first ++ + ++ second explicitly tells Java to split things up differently than above: it becomes (first ++) + (++ second), which is fine.

first + + + + + + second becomes first + (+ (+ (+ (+ (+ second))))). The unary + just means "not negated", so +foo == foo. Therefore this expression simplifies to first + second, which is obviously fine.

yshavit
  • 42,327
  • 7
  • 87
  • 124
  • 3
    Ooh, a positive unary operator. Didn't know that existed. And everything else makes sense. Cheers! – Sherz Aug 07 '14 at 14:55
  • So why is `second` incremented by 2 if the last expression evaluates to `first + second`? The OP states that `second` is equal to 22 after the last expression. – bcsb1001 Aug 07 '14 at 15:10
  • @bcsb1001 OP must have written the wrong output in the comment -- it doesn't increment as part of this expression. See https://gist.github.com/yshavit/c6a347b850bbc026e508 – yshavit Aug 07 '14 at 15:23
  • 2
    Ya, woops, my bad, I'll fix that for posterity. – Sherz Aug 08 '14 at 13:15
2

I don't want to close it as a duplicate since it's a different language but I believe it to be the same reason as layed out here.

It's simply a matter of parsing and these bullets should help you figure it out:

  • Java allows for a lot of whitespace
  • Consecutive mathematical operators like + bear no extra meaning and only one will be applied
  • Parsing is done from left to right

Code: first +++ second
Parsed: first++ + second

Code: first +++++ second
Parsed: There is no binary operator ++ since it will try to make ++ ++ +

Code: first ++ + ++ second
Parsed: first++ + ++second

Code: first + + + ++ second
Parsed: first + ++second

Code: first + + + + + + second
Parsed: first + second

Community
  • 1
  • 1
Jeroen Vannevel
  • 43,651
  • 22
  • 107
  • 170
0

I think the parser is greedy, i.e. it always eats as many plus-signs as available, for reducing them to the increment operator if possible.

I.e. it goes from left to right and when it spots two subsequent plus-signs, it evaluates them as increment operator, while a single plus sign followed by a non-plus-symbol is evaulated as a binary plus or as unary plus, depending on the left side operand.

RedXIII
  • 781
  • 7
  • 6