十进制文字大于LONG_LONG_MAX

时间:2018-05-26 21:03:44

标签: c++ c++11

在“C ++ Primer”一书中,据说十进制文字具有intlonglong long的最小类型,其中文字的值适合,这是一个错误使用太大而不适合最大相关类型的文字。所以,我想,最大十进制文字是long long可以容纳的最大值。 但我尝试了它:打印最大long long值,然后打印更高的十进制文字。我认为它必须导致错误,但它没关系。然后我尝试打印一个高于unsigned long long最大值的十进制文字 - 它缠绕着。

这是我的代码:

#include <iostream>
#include <limits>

using namespace std;

int main() {
    cout << LONG_LONG_MAX << endl;
    cout << 9223372036854775808 << endl;
    cout << ULONG_LONG_MAX << endl;
    cout << 18446744073709551616 << endl;
}

这是输出:

9223372036854775807
9223372036854775808
18446744073709551615
0

请解释一下,为什么十进制文字可能高于long long最大值

UPD

我注意到实际上有警告。我在CodeBlocks下工作,在重建和重新运行项目时,如果代码没有更改,它不会再次打印警告。所以我没注意到。有3个警告:

integer constant is so large that it is unsigned (8)
this decimal constant is unsigned only in ISO C90 (8)
integer constant is too large for its type (10)

但输出是一样的。然后我注意到在调试器选项中我忘了填写“可执行路径”行,所以我粘贴了我的gdb路径。但我认为这不重要。 之后我注意到我没有在编译器设置中选择'have g ++ follow c ++ 11'选项。我确实选择了编译器然后打印了警告和一些错误。没有this decimal constant is unsigned only in ISO C90警告,但是..\main.cpp|8|error: ambiguous overload for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and '<unnamed-signed:128>')|错误。此外,它无法使用LONG_LONG_MAX和ULONG_LONG_MAX识别limits,但使用LLONG_MAX和ULLONG_MAX识别climits。 使用c ++ 98时,会出现类似于第一种情况的警告(未选择任何选项),并且它无法识别limits,仅识别climits。当我更改标题名称时,输出就像在开头一样。 编译器设置为GNU GCC Compiler。

如果我没有指定标准,也许有人可以解释为什么编译器支持limits,然后,我认为问题已经关闭。

2 个答案:

答案 0 :(得分:2)

根据语言规范,没有后缀的十进制文字具有签名类型(可以保存值的intlong intlong long int的最小类型。二进制,八进制和十六进制常量可以有无符号类型。

允许实现支持扩展整数类型。如果编译器的整数类型大于long long,那么您的十进制文字将属于该类型。如果没有,则它是编译器错误或编译器扩展,因为未加语句的十进制文字不能是unsigned long long类型。

答案 1 :(得分:0)

请使用标准定义的标题和常量。 http://en.cppreference.com/w/cpp/types/climits

64位int的上限(大多数POSIX系统上的long long)是9223372036854775807(2 ^ 63-1)。 unsigned long long类型的对象的最大值int 18446744073709551615(2 ^ 64-1)。

<limits>可能存在,但不一定包括<climits>

由于您的文字不符合有符号值,编译器必须为您提供诊断(如果您没有禁用它),例如

main.c:8:13: warning: integer constant is so large that it is unsigned
    cout << 9223372036854775808 << endl;

显然gcc \ clang足够自由,可以考虑到这一点并且可以编译程序,假设该值将用无符号类型表示,并截断第二个文字。这是未确定的行为而前者不是真的,因此您可能会在输出中得到负值,例如:

9223372036854775807
-9223372036854775808
18446744073709551615
0