I tried to exercise KR 2.1 - to determine the range of long variables by direct calculation.
#include <stdio.h> #include <limits.h> int main() { unsigned short long_bits = sizeof( long ) * CHAR_BIT; printf( "LONG_MAX = %ld\n", ( 1L << ( long_bits - 1 ) ) - 1 ); printf( "LONG_MIN = %ld\n", ( -1 ) * ( 1L << ( long_bits - 1 ) ) ); printf( "ULONG_MAX (1) = %lu\n", ( 1UL << long_bits ) - 1 ); // doesn't work printf( "ULONG_MAX (2) = %lu\n", 2*( 1UL << ( long_bits - 1 ) ) - 1 ); // work printf( "\n" ); }
ULONG_MAX (1) = 0 incorrect, because I assume left shift overflow.ULONG_MAX (2) = 18446744073709551615 seems correct, replacing the last left shift by multiplying by 2.
So it looks like the left shift operator is suffering from overflow, but there is no multiplication? Does this intermediate calculation 2*( 1UL << ( long_bits - 1 ) ) do more to some type than long ? In my machine, long and long long exactly the same (8 bytes).
Edit: As Lundin noted, all that is required for ULONG_MAX is printf( "ULONG_MAX = %lu\n", ~0L );
Using a left shift in this case caused UB and multiplying by 2 is also potentially UB (although result 2 looks right).
source share