如何定义uint64_t常量?

How to define uint64_t constant?

我的 C++ 程序中有 uint64_t 常量(QtCreator 4.6.1 中的 clang 6.0.1)。

例如:

uint64_t a = 0xffffffffffffffffULL;

问题是,我在 IDE 中收到以下警告:

Warning: implicit conversion from 'unsigned long long' to 'uint64_t' (aka 'unsigned long')

我也尝试过将其更改为以下但没有成功:

uint64_t a = UINT64_C(0xffffffffffffffff);
uint64_t a = 0xffffffffffffffffUL;

我可以选择使用 C++14 标准和选项进行计算:-Wconstant-conversion

正在检查类型大小:

std::cout << "uint64_t " << sizeof (uint64_t) << std::endl; 
std::cout << "unsigned long " << sizeof (unsigned long) << std::endl;
std::cout << "unsigned long long " << sizeof (unsigned long long) << std::endl;

结果:

uint64_t 8  
unsigned long 8
unsigned long long 8

知道如何解决这个问题以及为什么 IDE 认为尺寸转换正在发生吗?

编辑:我刚刚检查了宏扩展:

define UINT64_C(c)  c ## UL

这意味着提供的示例应该有效,但它不起作用:

uint64_t a = 0xffffffffffffffffUL;

unsigned long long 至少是 64 位,所以它可能是比 uint64_t

更大的类型

我会写(注意 constexpr 的使用,因为它是一个常量):

#include <cinttypes>
#include <limits>
constexpr auto a = std::numeric_limits<std::uint64_t>::max();

并且要以可移植的方式定义一个非最大 uint64_t 常量,只需删除末尾的 ULL 部分:

constexpr std::uint64_t b = 0x12345;

编译器警告您在 C++ 中不保证大小相同的类型之间存在 隐式 转换。一种可能的解决方法是使其明确:

uint64_t a = static_cast<uint64_t>(0xffffffffffffffffULL);

这是一种方法:

auto a = static_cast<uint64_t>(-1);

这里首先要注意的是,您不需要 LL 后缀。

一个整型字面量会自动拥有一个可以容纳数字的类型。查看 this table 以获得确切的类型。此规则的唯一例外是如果您指定一个只适合 unsigned long long int 的十进制文字。然后你需要指定u后缀。

现在,可以通过强制转换轻松删除警告:

uint64_t a = (uint64_t)0xffffffffffffffff;

或者如果你不喜欢 C 演员表,那么 static_cast:

uint64_t a = static_cast<uint64_t>(0xffffffffffffffff);


到目前为止,这是理论,但您的 compiler/installation 有一些问题。如果您对此有隐式转换警告:

uint64_t a = 0xffffffffffffffffUL;

其中uint64_tunsigned long,那么就意味着0xffffffffffffffffUL实际上变成了unsigned long long int。但它不应该是,因为 sizeof(unsigned long) 已经是 8 了。如果编译和安装正确,这显然是不可能的情况。

由于@hvd 评论,此警告已解决。

检查了所有包含的头文件。由于某种原因,stdint.hcstdint 都包含在内。我只留下了cstdint。他们可能来自不同的平台并且有不同的定义。

工作示例:

uint64_t v0 = UINT64_C(0x736f6d6570736575);