72

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?

6 Answers 6

120

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)

7
  • Would unsigned long x = 1; x <<= 32; work, out of interest? Commented Nov 17, 2010 at 3:53
  • 1
    @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. Commented Nov 17, 2010 at 4:03
  • @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.
    – pynexj
    Commented Mar 18, 2013 at 5:34
  • @whjm: It may overflow. Signed integer overflow is undefined behavior.
    – Siyuan Ren
    Commented Mar 10, 2014 at 9:46
  • 3
    @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.
    – pynexj
    Commented Mar 17, 2014 at 5:33
21

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
1
  • 4
    IOW, it's the size of the constant 1 that's giving you problems, not x.
    – deStrangis
    Commented Oct 2, 2012 at 15:49
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.

1

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.

1

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 )

4
  • 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. Commented Oct 30, 2017 at 23:54
  • @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); } Commented Sep 18, 2018 at 21:27
  • @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. Commented Sep 18, 2018 at 21:32
  • 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 Commented Sep 18, 2018 at 21:37
-2

You can use something like that:

unsigned long x = 1;
x = x << 32;
1
  • 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. Commented Oct 23, 2018 at 21:48

Not the answer you're looking for? Browse other questions tagged or ask your own question.