Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is "-1>>5;" unspecified behavior in C?

C11 §6.5.7 Paragraph 5:

The result 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 / 2*^E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.

But, The viva64 reference document says:

int B; B = -1 >> 5; // unspecified behavior 

I ran this code on GCC and it's always give an output -1.

So, standard say's that "If E1 has a signed type and a negative value, the resulting value is implementation-defined", But that document say's that -1>>5; is unspecified behavior.

So, Is -1>>5; unspecified behavior in C? Which is correct?

like image 673
msc Avatar asked Oct 16 '17 18:10

msc


People also ask

Is unspecified behavior undefined behavior?

Unspecified behavior is different from undefined behavior. The latter is typically a result of an erroneous program construct or data, and no requirements are placed on the translation or execution of such constructs.

What is implementation defined Behaviour in C?

11.1 Implementation-defined behavior. This is how CPP behaves in all the cases which the C standard describes as implementation-defined . This term means that the implementation is free to do what it likes, but must document its choice and stick to it.


2 Answers

Both are correct. Implementation defined behavior is a particular type of unspecified behavior.

Citing section 3.4.1 of the C standard which defines "implementation-defined behavior":

1 implementation-defined behavior

unspecified behavior where each implementation documents how the choice is made

2 EXAMPLE An example of implementation-defined behavior is the propagation of the high-order bit when a signed integer is shifted right.

From section 3.4.4 defining "unspecified behavior":

1 unspecified behavior

use of an unspecified value, or other behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance

2 EXAMPLE An example of unspecified behavior is the order in which the arguments to a function are evaluated.

As for GCC, you'll always get the same answer because the operation is implementation defined. It implements right shift of negative numbers via sign extension

From the GCC documentation:

The results of some bitwise operations on signed integers (C90 6.3, C99 and C11 6.5).

Bitwise operators act on the representation of the value including both the sign and value bits, where the sign bit is considered immediately above the highest-value value bit. Signed >> acts on negative numbers by sign extension.

As an extension to the C language, GCC does not use the latitude given in C99 and C11 only to treat certain aspects of signed << as undefined. However, -fsanitize=shift (and -fsanitize=undefined) will diagnose such cases. They are also diagnosed where constant expressions are required.

like image 109
dbush Avatar answered Oct 04 '22 17:10

dbush


"Unspecified behavior" and "implementation defined" are not contradictory. It just means that the C standard does not specify what needs to happen, and that various implementations can do what they deem "correct."

Running it multiple times on one compiler and getting the same result only means that that particular compiler is consistent. You may get different results on a different compiler.

like image 28
skrrgwasme Avatar answered Oct 04 '22 19:10

skrrgwasme