Reputation: 30128
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
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