10

I am unable to grasp the idea of either addition operator or short data-type.

It's said that;

short a = 1;
short b = 2;
short c = a + b;

which will not compile because addition operator always cast short, chart, byte data-types to int and I understand this. But this;

short c = 1 + 2;

works totally fine. So, if addition operator auto converts short to int and then apply the result (where result ofcourse will be an int), why this works fine?

Edit: This question is not duplicate of Primitive type 'short' - casting in Java since I understand the conversions process. Also, the question talks about conversions of data types where as my question relates to int literals.

SSC
  • 2,956
  • 3
  • 27
  • 43
  • 9
    `1 + 2` can be calculated at compilation time since both operands are compilation time constants. In other words `short c = 1 + 2;` will be compiled as `short c = 3;`. You will still get error if result will be out of `short` range. – Pshemo Oct 21 '17 at 19:11
  • @Pshemo So that means, an `int` will be downcasted explicity to `short`? Because 1 + 2 either resolved as `short` will still be evaluate to `int`, no? – SSC Oct 21 '17 at 19:12
  • 5
    @dosdebug No, there is no addition here. It's compiled the same as `short c = 3;` – Neo Oct 21 '17 at 19:15
  • 3
    "So that means, an int will be downcasted explicity to short" if you are referring to *result of* `1+2` which at compilation time will be replaced by `3` then yes, same way as it is for `short a = 1;` and `short b = 2;`. – Pshemo Oct 21 '17 at 19:16
  • 1
    @Pshemo Thank you very much. That was super easy :D Compilation time magic can be very tricky ;) – SSC Oct 21 '17 at 19:17
  • 2
    @user140547 My friend it's not duplicate from any sense. – SSC Oct 21 '17 at 20:02
  • This [link] (https://www.w3resource.com/java-tutorial/java-arithmetic-operators.php) provides the basic conversions that happen when using Java Arithmetic operators. Hope this gives a clear idea on what operands get auto-converted when used with Java operators. – Keet Sugathadasa Oct 21 '17 at 20:06
  • 3
    well true, so I voting to reopen it. sorry – user140547 Oct 21 '17 at 20:20
  • Thank you for reopening. – SSC Oct 24 '17 at 10:47

2 Answers2

7

1 + 2 is a constant expression while a + b is not.
It matters on the evaluation of them.
The first one will be done at compile time, the second one at runtime.

The JLS 8 states :

15.28. Constant Expressions

A constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following:

  • Literals of primitive type and literals of type String (§3.10.1, §3.10.2, §3.10.3, §3.10.4, §3.10.5)

  • Casts to primitive types and casts to type String (§15.16)

  • The unary operators +, -, ~, and ! (but not ++ or --) (§15.15.3, §15.15.4, §15.15.5, §15.15.6)

  • The multiplicative operators *, /, and % (§15.17)

  • The additive operators + and - (§15.18)

........................

Here :

short c = 1 + 2;

1 + 2 is composed of two int literals and one additive operator.
So it is considered as a constant expression.
Constant expressions are evaluated at compile time.
So short c is evaluated as 3

Here is a sample class :

package stackoverflow;

public class EvaluationClass {

    public void foo(){
       short c = 1 + 2;
    }
}

Here is the disassembled code :

Compiled from "EvaluationClass.java"
public class stackoverflow.EvaluationClass {
  public stackoverflow.EvaluationClass();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()
       4: return

  public void foo();
    Code:
       0: iconst_3
       1: istore_1
       2: return
}

We can see the 0: iconst_3 instruction that loads the 3 int onto the stack.


Whereas here :

short a = 1;
short b = 2;
short c = a + b;

a + b is evaluated only at runtime as a and b are not constant values.
Their values may indeed change at anytime.
Note that the compiler doesn't try to be clever by reading each statement to guess if a and b effectively mutate.
It considers that it may and so evaluate a + b only at runtime.

Now in this case, why a + b doesn't produce a short but an int ?
Because the JLS 8 specifies that :

4.2.2. Integer Operations

If an integer operator other than a shift operator has at least one operand of type long, then the operation is carried out using 64-bit precision, and the result of the numerical operator is of type long. If the other operand is not long, it is first widened (§5.1.5) to type long by numeric promotion (§5.6).

Otherwise, the operation is carried out using 32-bit precision, and the result of the numerical operator is of type int. If either operand is not an int, it is first widened to type int by numeric promotion.


As a side note, if change your code to make a and b constants:

final short a = 1;
final short b = 2;
short c = a + b;

This will compile fine now as a + b would be evaluated as a constant expression (3).

davidxxx
  • 125,838
  • 23
  • 214
  • 215
  • Thank you. This has already been answered in question's comments. Thanks for the additional write up though. – SSC Oct 22 '17 at 06:08
0

As far as I understand, Java supports + for int and long, but as specified, not for short. There is no automatic type conversion, because the operation is specified to be performed on int or long datatypes.

See https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2

If you want to get a valid result, and know that the result doesn't cause an overflow, you can cast the result:

short a = 1;
short b = 2;
short c = (short)(a + b);
Christoph Bimminger
  • 1,006
  • 7
  • 25