为什么不长long int溢出?

时间:2015-01-06 08:46:04

标签: c linux long-integer

long long int a;
scanf("%lld",&a);
printf("n : %lld\n",a);

输入为9223372036854775808 (LLONG_MAX + 1)

但输出为9223372036854775807 (LLONG_MAX)

x64 GNU / Linux,我使用GCC编译器

5 个答案:

答案 0 :(得分:9)

scanf中的溢出会触发未定义的行为。

但是,scanf的许多流行实现都在内部使用strto...组中的函数将字符串转换为实际数字。 (或者,更确切地说,它们使用与strto...函数相同的低级实现原语。)strto...函数在溢出时生成目标类型的最大值。该实现的副作用是您在测试中观察到的。显然使用strtoll,在正溢出时产生LLONG_MAX

但你不应该依赖它,因为行为是未定义的。

答案 1 :(得分:4)

由于scanf会将输入限制在有效范围内,但会引发ERANGE错误,如this questionthe manpage中的回答:

  

如果之前达到输入结尾,则返回值 EOF   要么是第一次成功转换,要么是匹配失败。   如果发生读取错误,也会返回 EOF ,在这种情况下会出现错误   设置流的指示符(请参阅ferror(3)),并设置errno   表明错误。

...

  

ERANGE 整数转换的结果将超过其大小     可以存储在相应的整数类型中。

请注意,语言或POSIX标准并不要求这种行为,但对于许多标准库实现(包括您的标准库实现)来说,这显然是正确的。

答案 2 :(得分:1)

有符号溢出是未定义的行为。任何事情都可能发生。

答案 3 :(得分:1)

这是一种未定义的行为。在此,如果您将该值分配给变量而不是获取 从输入开始,那时你将在编译时收到警告。

答案 4 :(得分:0)

输出将无法预测。 我用简单的int尝试了同一段代码。 我附加了输出。 enter image description here