How to input int64_t / uint64_t constants?

2020-02-07 00:59发布

问题:

What I'm trying to do is to define a constant equal to 2^30 (I may change it to something like 2^34, so I prefer to have a room larger than 32 bits for it).

Why the following minimal(?) example doesn't compile?

#include <stdint.h>
// test.cpp:4:33: error: expected primary-expression before numeric constant
// test.cpp:4:33: error: expected ')' before numeric constant
const uint64_t test = (uint64_t 1) << 30;
//const uint64_t test1 = (uint64_t(1)) << 30;// this one magically compiles! why?

int main() { return 0; }

回答1:

(uint64_t 1) is not valid syntax. When casting, you can either use uint64_t(1) or (uint64_t) 1. The commented out example works because it follows the proper syntax for casting, as would:

const uint64_t test = ((uint64_t)1) << 30;

Edit: While this directly answers the question, see the answer by Shafik Yaghmour on how to properly define an integral constant with specific size.



回答2:

You can use the macro:

UINT64_C

to define a 64bit unsigned integer literal, the cstdint header provides macros for defining integer literals of specific sizes, we see that in section 18.4.1 Header synopsis:

The header also defines numerous macros of the form:

and includes:

plus function macros of the form:

[U]INT{8 16 32 64 MAX}_C

We have to go back to the C99 draft standard to find how they work, section 7.18.4.1 Macros for minimum-width integer constants which says:

[...]if uint_least64_t is a name for the type unsigned long long int, then UINT64_C(0x123) might expand to the integer constant 0x123ULL.

as the proper way of defining a 64bit integer constant expression. This is unfortunately not document on cpprefernce but cplusplus.com does document this feature for of the cstdint header as well as the posix reference for stdint.h.



回答3:

The syntax you are looking for is:

const uint64_t test = 1ULL << 30;

The post-fix ULL is used for unsigned integer literals that are at least 64-bits wide.