To optimize my cpp code, I’m trying to use Right Shifting in some case. Here is an example:

int main() { int i = (1 - 2) >> 31; // sizeof(int) == 4 ... ... }

I’ve printed the i and I got -1. It means that it will use 1 instead of 0 to fill in the empty position if the number is negative. In other words, -1 >> 31 works as below:

1111...1 <--- the result of (1 - 2), which is -1 1111...1 <--- -1 >> 31, 1 is used to fill in the empty position

I just want to know if this behavior is clearly defined or not?

If it is UB in cpp, how about in Java?

**Yes**. It is implementation-defined.

According to **C++03 5.8/3** which defines right-shifting:

The value of

E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has

an unsigned type or if E1 has a signed type and a nonnegative value,

the value of the result is the integral part of the quotient of E1

divided by the quantity 2 raised to the power E2.If E1 has a signed

type and a negative value, the resulting value is

implementation-defined.

For more information, see this link.

In **Java**, behavior of >> is **well-defined** for negative numbers (see below).

In **C++**, behavior of >> is **undefined** for negative numbers (see answer by rsp).

Quoting Java Language Specification, ยง15.19. Shift Operators:

The value of

nis>>snright-shiftedsbit positionswith sign-extension. The resulting value isfloor(n / 2. For non-negative values of^{s})n, this is equivalent to truncating integer division, as computed by the integer division operator /, by two to the powers.The value of

nis>>>snright-shiftedsbit positionswith zero-extension, where:

If

nis positive, then the result is the same as that ofn >> s.If

nis negative and the type of the left-hand operand is int, then the result is equal to that of the expression(n >> s) + (2 << ~s).If

nis negative and the type of the left-hand operand is long, then the result is equal to that of the expression(n >> s) + (2L << ~s).

By default it is signed int. The range is -32767 to 32767, bit wise range -111111111111111 to +111111111111111 the very first bit on the left acts as negative or positive indicator. And all the arithmetic operation will be done in 2’s complement method. In general negative int are represents in two complements method i.e take you example how -1 is represent.

4 Bytes = 32 bits 0000 0000 0000 0000 0000 0000 0000 0000 how represent 1 0000 0000 0000 0000 0000 0000 0000 0001 Then we invert the digits. 0 becomes 1, 1 becomes 0. 1111 1111 1111 1111 1111 1111 1111 1110 Then we add 1. 1111 1111 1111 1111 1111 1111 1111 1111 This is how -1 is represented

The right-shift of a negative number is defined to shift in 1s to the highest bit positions, then on a 2s complement representation it will behave as an arithmetic shift – the result of right-shifting by N will be the same as dividing by 2N, rounding toward negative infinity. So shifting of -1 is -1

now take an other number

For example,

if you have the 8-bit 2s complement binary number let represent -3

0000 0011 Then we invert the digits. 1111 1100 Then we add 1. 1111 1101

11111101 representing -3 in decimal, and you perform an arithmetic right shift by 1 to give 11111110 representing -2 in decimal, this is the same as dividing -3 by 2^1, giving -1.5 which rounds towards negative infinity resulting in -2.