warning: left shift count >= width of type
Solution 1
long
may be a 64-bit type, but 1
is still an int
. You need to make 1
a long int
using the L
suffix:
unsigned long x = 1UL << 32;
(You should also make it unsigned
using the U
suffix as I've shown, to avoid the issues of left shifting a signed integer. There's no problem when a long
is 64 bits wide and you shift by 32 bits, but it would be a problem if you shifted 63 bits)
Solution 2
unsigned long
is 32 bit or 64 bit which depends on your system. unsigned long long
is always 64 bit. You should do it as follows:
unsigned long long x = 1ULL << 32
Solution 3
The accepted solution is fine for [constant]ULL<<32 but no good for existing variables - e.g. [variable]<<32. The complete solution for variables is: ((unsigned long long)[variable]<<32). Aside: My personal opinion of this warning is that it is totally unnecessary in the first place. The compiler can see what the receiving data type is and knows the width of the parameters from the definitions in headers or constant values. I believe Apple could make the clang compiler a little more intelligent than it is regarding this warning.
Solution 4
unsigned long x = 1UL << 31;
Not show the error message. Because before you specify the 32, is not true because only limited to 0-31.
Solution 5
You can't shift a value to its max bit
int x; // let int be 4 bytes so max bits : 32
x <<= 32;
So, this generates the warning
left shift count >= width of type (i.e type = int = 32 )
Rupert Madden-Abbott
Updated on July 11, 2020Comments
-
Rupert Madden-Abbott almost 4 years
I'm very new to dealing with bits and have got stuck on the following warning when compiling:
7: warning: left shift count >= width of type
My line 7 looks like this
unsigned long int x = 1 << 32;
This would make sense if the size of
long
on my system was 32 bits. However,sizeof(long)
returns8
andCHAR_BIT
is defined as8
suggesting that long should be 8x8 = 64 bits long.What am I missing here? Are
sizeof
andCHAR_BIT
inaccurate or have I misunderstood something fundamental? -
Niet the Dark Absol over 13 yearsWould
unsigned long x = 1; x <<= 32;
work, out of interest? -
James McNellis over 13 years@Kolink: Yes, that would have the same effect, as would
(unsigned long)1 << 32
The left operand just has to be anunsigned long
. TheUL
suffix is just the most straightforward way to accomplish that. -
deStrangis over 11 yearsIOW, it's the size of the constant 1 that's giving you problems, not x.
-
pynexj about 11 years@James McNellis: What's the issues of left shifting a signed integer? I only know that right shifting a signed integer may leads to different result with different compilers.
-
Siyuan Ren about 10 years@whjm: It may overflow. Signed integer overflow is undefined behavior.
-
pynexj about 10 years@whjm: I just referred to the C99 standard and found following: 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 × 2 ** E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 × 2 ** E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
-
Matthieu almost 7 yearsAs it's "only" a warning, what should we assume when it will be run? Will
1 << 32
be just the same as1UL << 32
? Undefined behavior? -
underscore_d over 6 yearsYour wording is wrong. You can shift a
1
to the most significant bit of its type, if it'sunsigned
or if it'ssigned
and hasINT_MIN == 1 << width - 1
. It's shifting beyond that highest bit that can cause problems. -
Evan Carroll over 5 years@underscore_d no you can't try it (on an unsigned type).
int main(){ unsigned int x = 1 << 32; unsigned int y = 32; unsigned int z = 1 << y; printf("x:%d, z: %d\n", x, z); }
-
underscore_d over 5 years@EvanCarroll I think we are just all arguing at cross purposes about what "to its max bit" means, i.e. whether "to" means "by" and/or "max" means "most significant"... I was speaking in terms of shifting to the most significant bit, which is fine. What you and Vipul said,
1 << 32
i.e.1 << sizeof(T) * CHAR_BIT
, shits the1
one bit beyond that, which is a different matter. -
underscore_d over 5 yearsI fixed the typo of "byte". And you're still not getting it! Indexing bits from 1 at the least significant place:
1
is the 1st, least significant bit of a 32-bit type (which, by the way,unsigned int
is not necessarily). To shift that to the most significant bit, i.e. the 32nd bit, we shift left by 31, so we are then at 1 + 31 = the 32nd, most significant bit. I was quibbling with the wording and saying that doing this,1 << 31
in a 32-bit type, is fine. I'm not saying to do1 << 32
-
underscore_d over 5 yearsWhat? Why? How is this any different from the original code? It is still invalid. Any barely competent compiler would realise this and still warn. And even if it didn't, the code would still be ill-formed and have undefined behaviour if compiled.
-
Somebody almost 2 years@Matthieu since 1 is an
int
,1 << 32
simply shifts 1 out ofint
range, making the result 0