In C++, what is the difference between 1 and 1i64?

Nick Bolton picture Nick Bolton · Aug 12, 2009 · Viewed 9.2k times · Source

I'm converting some 32-bit compatible code into 64-bit - and I've hit a snag. I'm compiling a VS2008 x64 project, and I receive this warning:

warning C4334: '<<' : result of 32-bit shift implicitly converted to 64 bits
(was 64-bit shift intended?)

Here's the original line of code:

if ((j & (1 << k)) != 0) {

And here's what it looks like if I follow Microsoft's advice:

if ((j & (1i64 << k)) != 0) {

Is this safe to do, when the code will be compiled on both 32-bit and 64-bit systems? If so, please explain why I must add "i64" to the end, and why this will not affect a 32-bit compilation. Otherwise, a work-around would be much appreciated.

Beyond this, I have what looks like an even trickier bit of code.

if (id[j] != id[j ^ (1u << k)]) {

I understand that the "u" means that the digit is unsigned, but what's the point in specifying that on a value that doesn't exceed the signed maximum value... I'm guessing this has something to do with the bit shift?

Answer

Kirill V. Lyadvinsky picture Kirill V. Lyadvinsky · Aug 12, 2009

1 has type int according to C++ Standard. On 64-bit Microsoft compiler int has sizeof = 4 bytes, it means that int is 32-bit variable. 1i64 has type __int64.

When you use shift operator the type of the result is the same as the type of the left operand. It means that shifting 1 you'll get 32-bit result. Microsoft compiler assumes that it could be not what you are expecting (on 64-bit platform) and gives you warning message.

When you use 1i64 result will be 64-bit on both platforms. j and 0 will be implicitly casted to 64-bit. So the whole expression will be calculated in 64-bit variables and result will be bool.

So using 1i64 is safe on both (32/64) platforms.