warning: left shift count >= width of type

76,557

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 )

Share:
76,557
Rupert Madden-Abbott
Author by

Rupert Madden-Abbott

Updated on July 11, 2020

Comments

  • Rupert Madden-Abbott
    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) returns 8 and CHAR_BIT is defined as 8 suggesting that long should be 8x8 = 64 bits long.

    What am I missing here? Are sizeof and CHAR_BIT inaccurate or have I misunderstood something fundamental?

  • Niet the Dark Absol
    Niet the Dark Absol over 13 years
    Would unsigned long x = 1; x <<= 32; work, out of interest?
  • James McNellis
    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 an unsigned long. The UL suffix is just the most straightforward way to accomplish that.
  • deStrangis
    deStrangis over 11 years
    IOW, it's the size of the constant 1 that's giving you problems, not x.
  • pynexj
    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
    Siyuan Ren about 10 years
    @whjm: It may overflow. Signed integer overflow is undefined behavior.
  • pynexj
    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
    Matthieu almost 7 years
    As it's "only" a warning, what should we assume when it will be run? Will 1 << 32 be just the same as 1UL << 32? Undefined behavior?
  • underscore_d
    underscore_d over 6 years
    Your wording is wrong. You can shift a 1 to the most significant bit of its type, if it's unsigned or if it's signed and has INT_MIN == 1 << width - 1. It's shifting beyond that highest bit that can cause problems.
  • Evan Carroll
    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
    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 the 1 one bit beyond that, which is a different matter.
  • underscore_d
    underscore_d over 5 years
    I 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 do 1 << 32
  • underscore_d
    underscore_d over 5 years
    What? 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
    Somebody almost 2 years
    @Matthieu since 1 is an int, 1 << 32 simply shifts 1 out of int range, making the result 0