unsigned long long vs unsigned long(portability point of view)

21.5k views Asked by At

I want to be able to use large positive integers(8 bytes) in my project, even though sizeof(unsigned long) yields 8 in my system, I read that in most systems unsigned long is only 4 bytes and I decided to give unsigned long long a go, since it's guaranteed to be at least 8 bytes.

The more I use it though, I saw that it is not super portable as well, for instance in some systems(depending on the compiler) printf formats it with %llu, in some it formats it with %lld.

My code will only run in 64 bit debian machines, in which unsigned long will be 8 bytes. Portability is not a big issue. Is it an overkill to use unsigned long long over unsigned long under these circumstances, are there any other benefits of using unsigned long long over unsigned long?

3

There are 3 answers

7
James Kanze On BEST ANSWER

unsigned long long is guaranteed to be at least 64 bits, regardless of the platform. (There are platforms where it is more—I know of 72 bits and 96 bits—but they are rare, and decidedly exotic.) unsigned long is guaranteed to be at least 32 bits. If you need more than 32 bits, I would recommend unsigned long long.

With regards to the formatting, with printf, you should use "%llu" (since it is unsigned); "%lld" is for signed long long.

1
Cătălin Pitiș On

If you need to make sure you have a fixed size of the integer value, independent of platform, you could use boost::integers library (see here). You could use boost::int64_t or boost::uint64_t for unsigned values

0
Alexey Frunze On

You can do this if you want to stay with long and long long:

#include <limits.h>
#if ULONG_MAX >= 0xFFFFFFFFFFFFFFFFULL
typedef unsigned long uint64;
#else
typedef unsigned long long uint64;
#endif

W.r.t. this

in some systems(depending on the compiler) printf formats it with %llu, in some it formats it with %lld

printf() does not guess the format. You tell it the format.

If you want to printf a uint64 defined as in the above, do it like this:

printf("%llu", (unsigned long long)some_uint64_value);

You can typedef unsigned long long ulonglong; to make the cast easier to type.

There do exist other ways of doing the same, but not all compilers support them. This why I attached the ULL suffix to the number. In some compatibility modes in-between C89 and C99, 0xFFFFFFFFFFFFFFFF may be interpreted as an unsigned long, not unsigned long long, and will be truncated. The latest gcc by default runs in gnu89 mode for C code, not c99 or higher.