31

So, I expect this not to compile, and it doesn't:

// the two is inc'd, so reduces symbolically to println(int int)
// which is a compile error
System.out.println(1 ++ 2);

But this does:

System.out.println(1 + + 2);   // returns three

What gives? Shouldn't it also not compile?

Also, this question is very hard to search for because of the operators..

djeikyb
  • 4,470
  • 3
  • 35
  • 42
  • 1
    ++ is an increment operator so the compiler may be expecting a variable name either before or after ++ – ryekayo Dec 23 '14 at 17:37
  • 12
    In the second case `+` is a "syntactic sugar" operator (mirroring `-`) that does nothing to the operand. – Hot Licks Dec 23 '14 at 17:38
  • 4
    *"Also, this question is very hard to search for because of the operators.."* Why not search for 'Java operators'? You will get a list of operators and these operators are listed. – Radiodef Dec 23 '14 at 18:59
  • 3
    @Radiodef so once you search for "java operators" and you get hundreds of unrelated questions with the dozens of operator combinations Java uses, is there a way to further refine the search? – jabgibson Dec 23 '14 at 19:32
  • 1
    To search for symbols, use http://symbolhound.com/ (not sure it would solve this problem, but it's a useful resource) – Tim S. Dec 23 '14 at 20:44
  • 4
    [Analogous question in Java](http://stackoverflow.com/q/24279192/1157100) and [C#](http://stackoverflow.com/q/2528543/1157100). You can go even further, with `1 + + + + + 2`, in C [as in Python](http://stackoverflow.com/q/470139/1157100). – 200_success Dec 24 '14 at 04:51

5 Answers5

66

Java is interpreting the working 1 + + 2 as 1 plus positive 2. See the Unary operator section.

David says Reinstate Monica
  • 19,209
  • 22
  • 79
  • 122
ryanyuyu
  • 6,366
  • 10
  • 48
  • 53
41

From the Specification, on Lexical Translations

The longest possible translation is used at each step, even if the result does not ultimately make a correct program while another lexical translation would. There is one exception: if lexical translation occurs in a type context (§4.11) and the input stream has two or more consecutive > characters that are followed by a non-> character, then each > character must be translated to the token for the numerical comparison operator >.

(Also known as maximal munch.)

The ++ is interpreted as a postfix increment operator which cannot be applied to an integer literal, thus the compiler error.

While

1 + + 2

each character is interpreted separately. 1 is an integer literal, + is the additive operator, + is the unary plus operator, and 2 is an integer literal. The whole expression is equivalent to

1 + (+2)

which is easier to read.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
6

In Java/C++/C ++ is not same as + +. ++/-- are the Increment/Decrement operator. The first case does not work because it does not apply to literals (1 or 2). Even then it would not be a valid statement, Neither 1++ 2 nor 1 ++2 are valid statement in Java. The second example works because it is interpreted as 1 + (+2). The Java lexer ignores white space. ​In the same way this is valid :

1 + + + 2   --> 1 + (+ (+2))

Or

1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 2

​It works only because + is a unary operator. It does not work for strings as below :

"a" + + "b"   // does not work because +"b" is not valid.

Similarly it is not valid with multiplication

1 * * 2       // does not work because *2 is not valid.
fastcodejava
  • 39,895
  • 28
  • 133
  • 186
  • 1
    It isn't quite right to say the lexer ignores whitespace, eh? After all, it doesnt interpret `1++2` as `int biplus unplus int`, nor `1+ +2` as `int incr int` – djeikyb Dec 24 '14 at 14:35
3

The message is:

Main.java:14: error: ')' expected
        System.out.println(1 ++ 2);
                               ^

The 1 ++ 2 statement is parsed as 1 followed by ++ followed by 2. This is interpreted as 1++ and 2 creating a syntax error (and not an unexpected type error; in fact, you will get the same error if you used variables e.g. i ++ j).


The 1 + + 2 statement on the other hand is parsed as 1 followed by + followed by +2 which compiles as expected. The space between the two operators separates the two operators.

Salman A
  • 262,204
  • 82
  • 430
  • 521
3

Sometimes it's easier to see a problem using variables.

Your snippet could be rewritten as:

int a = 1;
int b = +2;
System.out.println(a + b); 

Now, you can easily see that the second + operator is used to indicate a positive value. You could also have written +1 + +2.

The - operator could be used to negate an expression.

+ and - are unary operators.

Pier-Alexandre Bouchard
  • 5,135
  • 5
  • 37
  • 72