我正在研究一个项目以更新20岁的代码,许多问题与整数溢出有关。我想确保正确测试溢出,所以我编写了一个测试程序。输出使我鼓舞。在这里是:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
int main (void) {
size_t largerNum,Num;
largerNum = 12;
Num = UINT_MAX;
printf("largerNum = %unNum = %unNum + 1 = %un", largerNum , Num, Num + 1);
largerNum = Num + 1;
printf("largerNum now = %un", largerNum);
if(largerNum < Num ){
printf("largerNum overflowed to %un", largerNum);
}
else {
printf("largerNum did not overflow: %un", largerNum);
}
printf("Is (0 < UINT_MAX)?n");
(0 < UINT_MAX)?printf("YESn"):printf("NOn");
printf("Is (largerNum < Num)?n");
(largerNum < Num)?printf("YESn"):printf("NOn");
return 0;
}
及其输出:
[afischer@susm603 /home/afischer/Fischer_Playground/overflowTest]$ main
largerNum = 12
Num = 4294967295
Num + 1 = 0
largerNum now = 0
largerNum did not overflow: 0
Is (0 < UINT_MAX)?
YES
Is (largerNum < Num)?
NO
我在这里和这里查看了其他一些帖子,并阅读了本文,但是它尚未使输出清楚地表明。有人以前看到了吗?
编辑:从size_t
更改为unsigned long
时,我让它起作用,这不应该做任何事情。
6 int main (void) {
7
8 unsigned long largerNum,Num;
9
10 largerNum = 12;
11 Num = UINT_MAX;
12
13 printf("largerNum = %unNum = %unNum + 1 = %un", largerNum , Num, Num + 1);
14
15 largerNum = Num + 2;
16
17 printf("largerNum now = %un", largerNum);
18
19 if(largerNum < Num ){
20 printf("largerNum overflowed to %un", largerNum);
21 }
22 else {
23 printf("largerNum did not overflow: %un", largerNum);
24 }
25
26 printf("Is (0 < UINT_MAX)?n");
27
28 (0 < UINT_MAX)?printf("YESn"):printf("NOn");
29
30 printf("Is (largerNum < Num)?n");
31
32 (largerNum < Num)?printf("YESn"):printf("NOn");
33
34
35 printf("largerNum = %un", largerNum);
36 printf("Num = %un", Num);
37
38 return 0;
39 }
输出:
[afischer@susm603 /home/afischer/Fischer_Playground/overflowTest]$ main
largerNum = 12
Num = 4294967295
Num + 1 = 0
largerNum now = 1
largerNum overflowed to 1
Is (0 < UINT_MAX)?
YES
Is (largerNum < Num)?
YES
largerNum = 1
Num = 4294967295
edit2:
阅读一些评论后,我将" uint_max"替换为" ulong_max",而三元运营商正常运行。然后,我将" size_t"更改为"未签名长"。而且它仍然可以正常工作。对我来说奇怪的是,在我的机器上," size_t"," unsigned int"one_answers" unsigned long"都是相同数量的字节,而'uint_max'和'ulong_max'是相同的值尽管一切都一样,但仍然会失败。也许不一样?这使我对c。
的理解感到不安对于那些有兴趣的人,工作代码:
6 int main (void) {
7 /* Can be size_t or unsigned long */
8 size_t largerNum,Num;
9
10 largerNum = 12;
11 Num = ULONG_MAX;
12
13 printf("largerNum = %unNum = %unNum + 1 = %un", largerNum , Num, Num + 1);
14
15 largerNum = Num + 2;
16
17 printf("largerNum now = %un", largerNum);
18
19 if(largerNum < Num ){
20 printf("largerNum overflowed to %un", largerNum);
21 }
22 else {
23 printf("largerNum did not overflow: %un", largerNum);
24 }
25
26 printf("Is (0 < ULONG_MAX)?n");
27
28 (0 < ULONG_MAX)?printf("YESn"):printf("NOn");
29
30 printf("Is (largerNum < Num)?n");
31
32 (largerNum < Num)?printf("YESn"):printf("NOn");
33
34
35 printf("largerNum = %un", largerNum);
36 printf("Num = %un", Num);
37
38 return 0;
39 }
输出:
[afischer@susm603 /home/afischer/Fischer_Playground/overflowTest]$ main
largerNum = 12
Num = 4294967295
Num + 1 = 0
largerNum now = 1
largerNum overflowed to 1
Is (0 < ULONG_MAX)?
YES
Is (largerNum < Num)?
YES
largerNum = 1
Num = 4294967295
最终编辑:
阅读了更多评论后,我发现我的printf()
语句错误。谢谢大家的帮助,现在一切都更有意义。= D
最终代码:
6 int main (void) {
7
8 unsigned long largerNum,Num;
9
10 largerNum = 12;
11 Num = ULONG_MAX;
12
13 printf("largerNum = %zunNum = %zunNum + 1 = %zun", larger Num, Num, Num + 1);
14
15 largerNum = Num + 2;
16
17 printf("largerNum now = %zun", largerNum);
18
19 if(largerNum < Num ){
20 printf("largerNum overflowed to %zun", largerNum);
21 }
22 else {
23 printf("largerNum did not overflow: %zun", largerNum);
24 }
25
26 printf("Is (0 < ULONG_MAX)?n");
27
28 (0 < ULONG_MAX)?printf("YESn"):printf("NOn");
29
30 printf("Is (largerNum < Num)?n");
31
32 (largerNum < Num)?printf("YESn"):printf("NOn");
33
34
35 printf("largerNum = %zun", largerNum);
36 printf("Num = %zun", Num);
37
38 return 0;
39 }
最终输出:
[afischer@susm603 /home/afischer/Fischer_Playground/overflowTest]$ main
largerNum = 12
Num = 18446744073709551615
Num + 1 = 0
largerNum now = 1
largerNum overflowed to 1
Is (0 < ULONG_MAX)?
YES
Is (largerNum < Num)?
YES
largerNum = 1
Num = 18446744073709551615
我的猜测是您的平台具有64位的size_t
,并且您使用错误的格式指定符打印size_t
,这是未定义的行为,并导致误导性输出。
要打印size_t
s,在GCC和Clang上使用%zu
,在MSVC上使用%Iu
。或者忘记所有这些,然后使用std::cout
打印结果。
使用VS2015上的%Iu
,我在64位编译器上获得的输出是
largerNum = 12
Num = 4294967295
Num + 1 = 4294967296
largerNum now = 4294967296
largerNum did not overflow: 4294967296
Is (0 < UINT_MAX)?
YES
Is (largerNum < Num)?
NO
只是添加到 @praetorian的答案中并显示一种安全实现:
#include <iostream>
#include <limits>
int main (void) {
using std::size_t;
using std::cout;
size_t largerNum = 12;
size_t Num = std::numeric_limits<size_t>::max();
cout << "largerNum = " << largerNum << "nNum = " << Num << "nNum + 1 = " << Num + 1 << "n";
largerNum = Num + 1;
cout << "largerNum now = " << largerNum << "n";
if(largerNum < Num ){
cout << "largerNum overflowed to " << largerNum << "n";
}
else {
cout << "largerNum did not overflow: " << largerNum << "n";
}
cout << "Is (0 < Unsigned Maximum)?n";
(0 < std::numeric_limits<size_t>::max())?cout << "YESn":cout << "NOn";
cout << "Is (largerNum < Num)?n";
(largerNum < Num)?cout << "YESn":cout << "NOn";
return 0;
}
因此:'printf'在C 中不是一个不错的选择,它不是类型的安全性(尽管好的编译器可以识别无效的格式指定器)。另一方面,iostream运算符很麻烦(对于许多人来说),如果必须将输出转换为不同的语言(例如:gnu getline),则很糟糕。您可以浏览网络以获取类型的安全格式字符串(例如:boost ::格式)