The new compiler is warning you about undefined behaviour which the old compiler did not warn you about. Be grateful, and finish your upgrade by moving to GCC 7.2.0, which is the latest GA version of GCC.
The C11 standard §6.5.7 Bitwise shift operators says:
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.
Since your result requires 52-bits, it is not representable in a 32-bit signed integer, and the compiler is correctly warning you that you're invoking undefined behaviour — which is something you should avoid doing.
There are many ways of fixing the problem, but perhaps this is the simplest fix — change the type of CLON
to unsigned
with the U
suffix (or you could use UL
or even ULL
if you really wanted unsigned long
or unsigned long long
results):
#define CLON 0x070707FD
#define ULON 0x070707FDU
int shift_CLON(void);
unsigned shift_ULON(void);
int shift_CLON(void)
{
return CLON << 24;
}
unsigned shift_ULON(void)
{
return ULON << 24;
}
When that code is in a file sw73.c
, you can compile it like so:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
> -Wstrict-prototypes -c sw73.c
sw73.c: In function ‘shift_CLON’:
sw73.c:9:17: error: result of ‘117901309 << 24’ requires 52 bits to represent, but ‘int’ only has 32 bits [-Werror=shift-overflow=]
return CLON << 24;
^~
cc1: all warnings being treated as errors
$