如何定义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_t
是unsigned long
,那么就意味着0xffffffffffffffffUL
实际上变成了unsigned long long int
。但它不应该是,因为 sizeof(unsigned long)
已经是 8 了。如果编译和安装正确,这显然是不可能的情况。
由于@hvd 评论,此警告已解决。
检查了所有包含的头文件。由于某种原因,stdint.h
和 cstdint
都包含在内。我只留下了cstdint
。他们可能来自不同的平台并且有不同的定义。
工作示例:
uint64_t v0 = UINT64_C(0x736f6d6570736575);
我的 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_t
是unsigned long
,那么就意味着0xffffffffffffffffUL
实际上变成了unsigned long long int
。但它不应该是,因为 sizeof(unsigned long)
已经是 8 了。如果编译和安装正确,这显然是不可能的情况。
由于@hvd 评论,此警告已解决。
检查了所有包含的头文件。由于某种原因,stdint.h
和 cstdint
都包含在内。我只留下了cstdint
。他们可能来自不同的平台并且有不同的定义。
工作示例:
uint64_t v0 = UINT64_C(0x736f6d6570736575);