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?
is there any difference between n/=10 and n=n/10 in execution speed wise? just like n-- and --n are differ in their execution speed wise also... n/=10 theoretically doesn't create a temporary, while n=n/10 theoretically does, but in practice it would be optimised by the compiler anyway.
The i64 suffix is a Microsoft extension to specify 64-bit integer constants. A portable alternative is (int64_t)9223372036854775807 , but older versions of Microsoft C did not support C99 <stdint.
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.
The i64
suffix is Microsoft-specific. To be more portable (if you're worried about that), you might use the INT64_C()
macro from stdint.h
:
#include <stdint.h>
// ...
if ((j & (INT64_C( 1) << k)) != 0) { ... }
Unfortunately, MS doesn't have stdint.h
as part of their C library (most other compilers seem to have it), but fortunately you can get one from several sources:
Now you'll have a 64-bit constant that'll work with a wide variety of compilers.
As far as why you might want or need the 64-bit value, it depends on the types of the various parts of the expression. It would be helpful to know the types of id
, j
, and k
to be able to answer whether you need the the 'u
' suffix on the constant or not, and what effect it might have.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With