Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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?

like image 390
Nick Bolton Avatar asked Aug 12 '09 03:08

Nick Bolton


People also ask

What is difference between N 10 and n10?

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.

What is i64 in C?

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.


2 Answers

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.

like image 136
Kirill V. Lyadvinsky Avatar answered Sep 18 '22 03:09

Kirill V. Lyadvinsky


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:

  • http://snipplr.com/view/18199/stdinth/
  • http://msinttypes.googlecode.com/svn/trunk/stdint.h
  • http://www.azillionmonkeys.com/qed/pstdint.h

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.

like image 29
Michael Burr Avatar answered Sep 20 '22 03:09

Michael Burr