C语言有符号整数溢出

示例

根据C99和C11的第6.5 / 5段,如果结果不是表达式类型的可表示值,则对表达式求值会产生未定义的行为。对于算术类型,这称为溢出无符号整数算术不会溢出,因为第6.2.5 / 9段适用,导致任何超出范围的无符号结果都将减小为范围内的值。但是,对于有符号整数类型没有类似的规定。这些可以并且确实会溢出,从而产生不确定的行为。例如,

#include <limits.h>      /* to get INT_MAX */

int main(void) {

    int i = INT_MAX + 1; /* Overflow happens here */

    return 0;

}

这种类型的不确定行为的大多数实例更难以识别或预测。从原理上讲,溢出可能是对有符号整数进行任何加,减或乘运算(取决于常规的算术转换)而导致的,即没有有效界限或操作数之间没有防止此关系的关系。例如,此功能:

int square(int x) {

    return x * x;  /* overflows for some values of x */

}

是合理的,并且对于足够小的参数值它是正确的,但是对于较大的参数值,它的行为是不确定的。您不能仅通过函数来判断调用它的程序是否表现出未定义的行为。这取决于他们传递给它什么参数。

另一方面,请考虑以下这个简单的溢出安全有符号整数算术示例:

int zero(int x) {

    return x - x;  /* Cannot overflow */

}

减法运算符的操作数之间的关系确保了减法永远不会溢出。或者考虑以下更实际的示例:

int sizeDelta(FILE *f1, FILE *f2) {

    int count1 = 0;

    int count2 = 0;

    while (fgetc(f1) != EOF) count1++;  /* might overflow */

    while (fgetc(f2) != EOF) count2++;  /* might overflow */

    return count1 - count2; /* provided no UB to this point, will not overflow */

}

只要计数器不会单独溢出,最终减法的操作数都将为非负数。任意两个这样的值之间的所有差异都可以表示为int。

以上是 C语言有符号整数溢出 的全部内容, 来源链接: utcz.com/z/350089.html

回到顶部