This is for a C89 project, in which
(1L<<n) - 1
If you know the mathematical value of
(1L<<n)-1 fits in
long, you can ensure you don't overflow by calculating the value minus one, and then adding one, rather than calculating the value plus one, and then subtracting one.
n == 0 ? 1 : ((1L<<n-1)-1<<1)+1
It's convoluted, requiring special casing to avoid left shift by a negative value if
n == 0, but at least it gets you the value you need.
Alternatively, you can use a right shift:
#ifdef LONG_IS_64BIT 0x7FFFFFFFFFFFFFFF>>(63-n) #else 0x7FFFFFFF>>(31-n) #endif
You can't use
LONG_MAX here if it could well be larger than you expect.
Realistically though, @melpomene's comment to use
unsigned long should be good enough. The platforms where it has the same amount of value bits as
long were already uncommon back when the standard was written. And if you already sort of assume
long will have exactly 32 or exactly 64 bits, you probably shouldn't worry about the more esoteric implementations.