NoSenseEtAl
NoSenseEtAl

Reputation: 30128

Purpose of using UINT64_C?

I found this line in boost source:

const boost::uint64_t m = UINT64_C(0xc6a4a7935bd1e995);

I wonder what is the purpose of using a MACRO here?

All this one does is to add ULL to the constant provided.

I assume it may be used to make it harder for people to make mistake of typing UL instead of ULL, but I wonder if there is any other reason to use it.

Upvotes: 7

Views: 9670

Answers (1)

Miles Budnek
Miles Budnek

Reputation: 30629

If you look at boost/cstdint.h, you can see that the definition of the UINT64_C macro is different on different platforms and compilers.

On some platforms it's defined as value##uL, on others it's value##uLL, and on yet others it's value##ui64. It all depends on the size of unsigned long and unsigned long long on that platform or the presence of compiler-specific extensions.

I don't think using UINT64_C is actually necessary in that context, since the literal 0xc6a4a7935bd1e995 would already be interpreted as a 64-bit unsigned integer. It is necessary in some other context though. For example, here the literal 0x00000000ffffffff would be interpreted as a 32-bit unsigned integer if it weren't specifically specified as a 64-bit unsigned integer by using UINT64_C (though I think it would be promoted to uint64_t for the bitwise AND operation).

In any case, explicitly declaring the size of literals where it matters serves a valuable role in code-clarity. Sometimes, even if an operation is perfectly well-defined by the language, it can be difficult for a human programmer to tell what types are involved. Saying it explicitly can make code easier to reason about, even if it doesn't directly alter the behavior of the program.

Upvotes: 12

Related Questions