【发布时间】:2021-02-14 04:27:27
【问题描述】:
我试图以字节为单位表示 16gb,uint64_t 抛出错误。
我应该使用哪种数据类型来表示它?
unsigned long int 也会抛出错误。
error: integer overflow in expression [-Werror=overflow]
uint64_t TESTBYTES = 16 * 1024 * 1024 * 1024;
【问题讨论】:
我试图以字节为单位表示 16gb,uint64_t 抛出错误。
我应该使用哪种数据类型来表示它?
unsigned long int 也会抛出错误。
error: integer overflow in expression [-Werror=overflow]
uint64_t TESTBYTES = 16 * 1024 * 1024 * 1024;
【问题讨论】:
uint64_t TESTBYTES = 16ULL * 1024 * 1024 * 1024 会做到的。
否则,表达式 16 * 1024 * 1024 * 1024 被评估为 int,在您的平台上具有未定义的结果,因为您溢出了 int 类型。
ULL 将第一个术语提升为 unsigned long long,强制提升其他术语。这是始终安全的,因为unsigned long long 需要至少为 64 位。
【讨论】:
uint64_t TEST1BYTES 的变量并向其添加 64 字节......就像 TEST1BYTES+=64;一旦达到限制,它将引发错误。顺便说一句,谢谢
uint64_t 必须回绕为零,因此不会引发错误。但是您最好通过连续添加 64 来溢出 64 位无符号;即使每纳秒增量也需要几年时间。
按原样,您的表达式由不带后缀的integer literals 组成,并将被评估为有符号整数,并且值将溢出。表达式的结果是17179869184,32 位整数可以容纳的最大值是2147483647,所以它会溢出。要强制将表达式评估为无符号(在您的情况下为无符号长长)值,您应该将 ULL 或 ull 后缀添加到您的操作数之一(除了 cmets 中指出的最后一个),以便整个表达式被评估为unsigned long long。演示发生了什么的简单示例:
#include <iostream>
#include <cstdint>
#include <limits>
int main() {
uint64_t x; // unsigned long long
auto y = 16 * 1024 * 1024 * 1024; // evaluated as int, the result overflows
auto z = 16ull * 1024 * 1024 * 1024; // evaluated as unsigned long long, does not overflow
std::cout << "Your expression: " << z << '\n';
std::cout << "Maximum integer value: " << std::numeric_limits<int>::max() << '\n';
std::cout << "Maximum unsigned long long value: " << std::numeric_limits<unsigned long long>::max() << '\n';
x = z;
}
【讨论】:
int 的平台上易受攻击。
uint64_t CapacityBytes[] = {16ULL * 1024 * 1024 * 1024, 16ULL * 1024 * 1024 * 1024};
y 行说“结果不适合”是不正确的
error: too many initializers for ‘uint64_t [0],而不是我们有乘法表达式.. 因为 unint64_t[2].. 有效