为什么使用大整数时,C语言没有返回错误

3

你好,我正在学习C语言,我在声明 signed int testing=4294967295; 时犯了一个错误。虽然我知道可以创建一个这样大小的无符号整数,但是我认为有符号整数的范围是-2,147,483,648到2,147,483,647,因此我期望会发生溢出错误,但是并没有发生。请问有人能告诉我为什么会这样吗?

3个回答

4

signed int 溢出会导致未定义的行为。编译器可能会或可能不会产生任何警告或错误。

C11: 3.4.3 (p3):

整数溢出是未定义行为的一个例子。


2
还应该注意,强烈建议始终开启警告编译选项(比如在GCC或Clang中使用-Wall-Wextra提供更多的警告,但我不推荐使用后者)。警告很可能会在编译时捕捉到这样的问题(尽管编译器并非必须这样做,大多数都会)。 - Tim Čas
1
这并不是UB,因为没有溢出(在C标准的意义下),只是从long(或常量所具有的任何类型)到int的实现定义转换(或引发实现定义的信号)。 - mafso
1
@Tim,为什么你不建议使用后者(-Wextra)? - Spikatrix
1
@CoolGuy:过于冗长,有很多误报。例如,警告未使用的函数参数(可能是由于API,比如带有未使用的“userdata”指针的回调)或警告缺少字段初始化程序(当您有意使用“{0}”初始化结构时,使编译器自动将其他所有内容都初始化为零)。 - Tim Čas
@Tim,我很惊讶看到“-Wextra”有一些误报。我试着在谷歌上搜索,但没有找到答案。所以我在SO上提了一个问题 - Spikatrix
@酷哥: 我不会在那里回答,因为已经有很多答案了;但我确实在问题和被接受的答案上发表了评论。我知道很多人赞同我关于-Wextra选项的观点(提示:这就是为什么它没有包含在-Wall选项中的原因!),尽管显然在SO上赞同的人不太多。 - Tim Čas

1

溢出并不是错误,它只是int类型的一种行为。我猜在你的情况下,当发生溢出时,你的int类型变量所存储的值与你设定的值不同。

尝试打印int类型的值。根据你的设置和硬件,可能会发生很多奇怪的事情,但你会看到一些奇怪的行为。


1

C标准规定:

如果在表达式求值过程中出现异常情况(即,结果在其类型的表示范围内无法定义或不可表示),则行为未定义。

这意味着如果发生溢出,你就没有任何保障了 - 没有任何一种行为是保证的。无符号类型是一个特殊情况,永远不会发生溢出。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接