uintmax_t不处理128位

时间:2015-01-20 19:40:57

标签: c++ compiler-errors primitive-types

我想在我的代码中定义千兆字节,所以我首先使用unsigned long。但是,unsigned long无法处理2 * gigabyte

所以,我用long long替换它,但我得到了相同的编译错误/警告:     错误:表达式中的整数溢出[-Werror = overflow]

最后,我查找了大整数,发现uintmax_t是我需要的,因为它是128位。

不幸的是,我仍然遇到同样的错误。我想有一个小故障但我能找到它。

请在下面找到相关代码:

#define kilobyte 1024
#define megabyte 1024 * kilobyte
#define gigabyte 1024 * megabyte
uintmax_t threshold = 2 * gigabyte;

最后,在运行' make'

之后
g++ -Wall -Wextra -Werror -pedantic -pthread -std=c++0x -g  -o lcr main.cpp

我得到了:

main.cpp: In function ‘int main(int, char**)’:
main.cpp:104:17: error: integer overflow in expression [-Werror=overflow]
cc1plus: all warnings being treated as errors

2 个答案:

答案 0 :(得分:4)

两个int的产品显然仍然是int类型的产品 - 我们在您的宏中处理的文字属于int类型。
1024 3 = 2 30 几乎可以在32位int中表示。但是, 2 * 2 30 = 2 31 对于32位带符号的int来说太大了。

这可以通过将常量定义为适当类型的对象来解决:

const std::uintmax_t kilobyte = 1024;
const std::uintmax_t megabyte = 1024 * kilobyte;
const std::uintmax_t gigabyte = 1024 * megabyte;
const std::uintmax_t threshold = 2 * gigabyte;

由于在*的操作数上执行通常的算术转换,因此不会发生溢出。

答案 1 :(得分:3)

让我们看一段代码:

uintmax_t x = 2 * 1024;

这里发生了什么,我们有(int) 2 * (int) 1024,然后我们将结果提升为uintmax_t

相反,我们想要:(uintmax_t) 2 * (uintmax_t) 1024。我们可以通过这种方法轻松地将整数提升为long long

#define kilobyte 1024ULL
#define megabyte 1024ULL * kilobyte
#define gigabyte 1024ULL * megabyte
uintmax_t threshold = 2ULL * gigabyte;