Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is 1 << 31 well defined in C when sizeof(int) == 4

Tags:

According to the answer to this questions:

The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1 × 2E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.

Which seems to imply that 1 << 31 is undefined.

However GCC doesn't issue a warning if I use 1 << 31. It does issue one for 1 << 32. link

So which is it? Am I misunderstanding the standard? Does GCC have its own interpretation?

like image 694
Ilya Lesokhin Avatar asked Jul 23 '17 18:07

Ilya Lesokhin


1 Answers

No: 1 << 31 has undefined behavior if the type int has only 31 value bits.

1U << 31 is OK and evaluates to 0x80000000 if type unsigned int has 32 value bits.

On a system where bytes have 8 bits, sizeof(int) == 4 means int has at most 31 value bits, so shifting 1 by 31 places is undefined. Conversely, on a system where CHAR_BIT > 8, it may be OK to write 1 << 31.

gcc might issue a warning if you raise the warning level. try gcc -Wall -Wextra -W -Werror. clang does issue a warning with the same options.

To address Michaël Roy's comments, 1 << 31 does not evaluate to INT_MIN reliably. It might give this value on your system, but the Standard does not guarantee it, in fact the Standard describes this as undefined behavior, so not only can you not rely on it, you should avoid it to avoid spurious bugs. The optimizers routinely take advantage of potential undefined behavior to remove code and break the programmers' assumptions.

For example, the following code might compile to a simple return 1;:

int check_shift(int i) {    if ((1 << i) > 0)        return 1;    else        return 0; } 

None of the compilers supported by Godbolt's compiler explorer do, but doing so would not break conformity.

like image 140
chqrlie Avatar answered Sep 22 '22 01:09

chqrlie