37

Came across someone mistakenly using =+ instead of += in their code and it didn't show up as a compile error.

Is this because

int a =+ 2;

is the same as

int a = 0 + 2;

?

Scimonster
  • 32,893
  • 9
  • 77
  • 89
Markus Tonsaker
  • 479
  • 5
  • 15
  • 1
    Apologies, I mis-read the question as += not =+ – Jon Story Dec 09 '14 at 14:15
  • 20
    This has a distinct similarity to the `-->` "operator" (as in [`while (x --> 0) { /*...*/ }`](http://stackoverflow.com/questions/1642028/what-is-the-name-of-the-operator)) – geometrian Dec 09 '14 at 15:49
  • 1
    The `=` and `+` operators were smashed together as they were in [=+ Operator in Java](http://stackoverflow.com/questions/19236010/operator-in-java). – rgettman Dec 09 '14 at 18:52
  • 2
    Why so many upvotes? I'm sure this isn't the first time this has been asked. – David G Dec 09 '14 at 21:46
  • 3
    Why vote for reopen when [=+ Operator in Java](http://stackoverflow.com/questions/19236010/operator-in-java) already has an [answer](http://stackoverflow.com/a/19236069/76722)? – Sebastian Mach Dec 10 '14 at 13:55
  • Why is this a "duplicate"? The question doesn't mention java. In C++, where the unary + can be overloaded, this is a valid question. – Dmitry Rubanovich Dec 10 '14 at 17:44
  • 2
    @Dmitry: the question's tagged [tag:Java]. – Mac Dec 10 '14 at 22:13
  • 1
    @phresnel Admittedly, I do have some skin in the game, but I think the two questions are different enough for this one to not be considered a duplicate. If it were not for the answer, the original question could actually be closed as a *simple typographical error*, where as this question already starts from the idea that a mistake was made and asks for reasons as why this mistake doesn't result in a compilation error. – Robby Cornelissen Dec 11 '14 at 00:52

2 Answers2

105

There's no compilation error because + is a valid (albeit fairly useless) unary operator in the same way that - is:

int x = +1;
int y = -1;

The relevant section in the Java Language Specification is Unary Plus Operator + (§15.15.3 ). It specifies that invoking the unary + operation results in Unary Numeric Promotion (§5.6.1) of the operand. This means that:

  • If the operand is of compile-time type Byte, Short, Character, or Integer, it is subjected to unboxing conversion (§5.1.8). The result is then promoted to a value of type int by a widening primitive conversion (§5.1.2) or an identity conversion (§5.1.1).

  • Otherwise, if the operand is of compile-time type Long, Float, or Double, it is subjected to unboxing conversion (§5.1.8).

  • Otherwise, if the operand is of compile-time type byte, short, or char, it is promoted to a value of type int by a widening primitive conversion (§5.1.2).

  • Otherwise, a unary numeric operand remains as is and is not converted.

In any case, value set conversion (§5.1.13) is then applied.

In short, this means that

  1. numeric primitive wrapper types are unboxed, and;
  2. integer types smaller than int are widened to int.
Robby Cornelissen
  • 91,784
  • 22
  • 134
  • 156
  • 16
    Useless is relative ;) Maybe you like monospace lines. – Lan Dec 09 '14 at 03:47
  • 2
    Yeah, I just added "fairly" before useless :-) – Robby Cornelissen Dec 09 '14 at 03:47
  • No more or less useless than -. – BlamKiwi Dec 09 '14 at 04:13
  • 9
    @MorphingDragon That doesn't make sense. `-` allows you to have negative literals. The unary `+` is redundant with no operator at all, making it much less useful than `-`. – jpmc26 Dec 09 '14 at 05:46
  • 2
    @jpmc26 It may be vestigial from C++, which has operator overloading and can make good use of it. This, of course, makes Java's lack of either doubly sad. – geometrian Dec 09 '14 at 06:04
  • 1
    @jpmc26 No, `-` is still an operator. You do not actually have a negative literal. The compiler evaluates the expression unary-minus applied to a literal, and resolves that into a negative number at compile-time, just as it would had you written the equivalent `(0 - 123)` instead of `-123`. – tchrist Dec 09 '14 at 06:14
  • @imallett In what situation would overloading the unary `+` be a good idea? Can anyone think of one? – Bob Dec 09 '14 at 08:44
  • @Bob I'd say mainly when writing a DSL. I believe Boost.Spirit does it to represent the regex operator `+`. – Angew is no longer proud of SO Dec 09 '14 at 09:56
  • 18
    @jpmc26 `+` is not really redundant, it forces [unary numeric promotion](https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.1) on the operand (which includes e.g. unboxing). – Angew is no longer proud of SO Dec 09 '14 at 09:58
  • 6
    Whilst this is a Java question, I will also point out that using unary + is a common shorthand technique in some langauges (e.g. Javascript) for casting to a number. e.g. given a string `var s = '123';` then `+s` will evaluate to the number 123. – dty Dec 09 '14 at 10:46
  • 1
    @tchrist I apologize for fudging the terminology, but I sure don't know of any other way of writing a negative number without getting convoluted. The point is that this makes `-` significantly more *useful*. – jpmc26 Dec 09 '14 at 11:17
  • 2
    @Angew It's still redundant in recent versions of Java since unboxing happens automatically, at least in a majority of cases. – jpmc26 Dec 09 '14 at 11:18
  • 1
    @tchrist: except for `int x = -2147483648` which can *not* expressed as `int x = 0-2147483648`… – Holger Dec 09 '14 at 11:27
  • 1
    The ability to write a `+` sign explicitly has an advantage where clarity is required. E.g. within a *comparator*, I always write `+1` rather than simply `1`, e.g. `return condition? +1: -1;`. If you want to talk about a real useless feature, how about the ability to write `+ + + + 1`… – Holger Dec 09 '14 at 11:31
  • 1
    @LightnessRacesinOrbit You make a good point, but since this question is marked Java, how about `char number = 5; System.out.println(+number);` – Nicu Stiurca Dec 09 '14 at 12:49
  • 28
    `+` is not useless. It lets you create ASCII art like `(d+,+b)`. – tckmn Dec 09 '14 at 12:59
  • So, except for its merits in the creation of ASCII art, and the fact that it could improve the clarity of certain expressions, nobody is able to come up with an actual example in which unary `+` provides added value in Java? Disappointing but not entirely unexpected. – Robby Cornelissen Dec 09 '14 at 14:11
  • @Bob : prepending `+` to a lvalue decays it, for example an array name (to a pointer to its first element) or a lambda (to a function pointer, if applicable). – Quentin Dec 09 '14 at 16:31
  • @Bob Not really a related language, but just for an example of what could be done: in javascript, unary `+` is shorthand to convert a string containing a number into an actual number – Izkata Dec 09 '14 at 18:01
  • @Holger: Oh sorry. I thought this question was in the C or C++ tag. I'll delete my irrelevant comment. – R.. GitHub STOP HELPING ICE Dec 09 '14 at 20:43
  • 2
    @Robby Cornelissen: why is this disappointing? Orthogonality in a programming language isn’t a bad thing even if it allows “useless” expressions. I guess, you would be *really surprised* if, e.g. a programming language having a typical multiplication operator `*` produces a compiler error for the expression `foo * 1` because it’s “useless”. So, for languages supporting unary `-`, everyone expects the presence of a unary `+` as well, and not meeting that would violate the principle of the least surprise. – Holger Dec 10 '14 at 09:25
  • @Holger I agree with you and for the sake of orthogonality the operator should indeed exist and behave as it does. The reason I was slightly disappointed is that, although there was a flurry of comments (some deleted now) railing against my calling the operator "useless", nobody was able to demonstrate any practical use. – Robby Cornelissen Dec 10 '14 at 09:54
  • I don't believe the question was Java specific. In C++, the unary plus can be used as a way to do what Java calls "unboxing". But it does more. Because you get to define its return type, it's more than an explicit cast. It's unboxing to a fixed type. So that you can have cast operators overloaded to (let's say) char and const char, but have the unary + overloaded to return an int. This will make a difference when you try to print the value of the class. printf() is only aware of primitive types, but at least you know the type. Can also be useful with operator<<() – Dmitry Rubanovich Dec 10 '14 at 17:42
  • @DmitryRubanovich It's tagged with Java, so I'm pretty sure it's Java specific. – jpmc26 Dec 10 '14 at 23:22
  • I think Java does leave room for possible future primitive operator overloading (a la reserving, but not utilizing keyword "goto"). This would make a unary plus a more reasonable parse of the statement in question "=+" than making it a synonym of "+=". Simply because, otherwise, an overloadable unary plus would break too much code in the future. – Dmitry Rubanovich Dec 13 '14 at 06:16
35

There may be a bug lurking here. The writer may have intended to write a += 2;

In the original version of C, a += 2; and a =+ 2; were synonyms. If you meant a = +2;, you had to be careful to leave a space between the = and the +. Same with all the other operators. a=*p; multiplied a by p. a = *p; de-referenced the pointer p and assigned the result to a.

Then they came to their senses, and started giving warnings for =op where op= was probably intended, and now no longer accept =op at all.

But old habits die hard. An old-school C programmer might might still absent-mindedly use old-school syntax, even when writing in a language other than C.

On the other hand, the = in int x =+ 2; is an initialization, not an assignment, and it would be bizarre for a programmer to think in terms of incrementing a variable that is only just now being given its initial value.

ganbustein
  • 1,593
  • 11
  • 10
  • 8
    I like your answer, but it's probably just a typo, especially if it's a newer programmer--epxerienced programmers such as myslef never swtich characters like that. – ajb Dec 09 '14 at 04:30
  • 13
    Do you have a source for the alternate `=+` syntax, besides experience, that I can read more from? – geometrian Dec 09 '14 at 06:06
  • 4
    There was a brief period in the mid-70s when the notations coexisted in C but the old `=+` notation was no longer valid by the time of 7th Edition Unix in 1978. – Jonathan Leffler Dec 09 '14 at 07:30
  • 11
    @imallett, http://cm.bell-labs.com/cm/cs/who/dmr/chist.pdf, page 5: `(In B and early C, the operator was spelled =+ instead of += ; this mistake, repaired in 1976...` – Roger Lipscombe Dec 09 '14 at 11:52
  • 3
    That `=*` operator seems like a nightmare of a debugging session just waiting to happen... – Blindy Dec 09 '14 at 16:04