1、检查加法溢出
对于无符号整数加法,溢出发生在结果小于操作数的情况。
#include <stdio.h>
#include <limits.h>
int main() {
unsigned int a = UINT_MAX; // 最大无符号整数
unsigned int b = 1;
unsigned int result = a + b;
// 检查溢出
if (result < a) {
printf("无符号整数加法发生溢出\n");
} else {
printf("结果为: %u\n", result);
}
return 0;
}
2、检查乘法溢出
无符号整数乘法溢出可以通过检查结果是否小于某个操作数来检测。
#include <stdio.h>
#include <limits.h>
int main() {
unsigned int a = UINT_MAX / 2 + 1;
unsigned int b = 3;
unsigned int result = a * b;
// 检查溢出
if (a != 0 && result / a != b) {
printf("无符号整数乘法发生溢出\n");
} else {
printf("结果为: %u\n", result);
}
return 0;
}
3、使用宽类型
在进行无符号整数运算之前,将其转换为更宽的类型(如 unsigned long long
),然后检查是否超过原始类型的限制。
#include <stdio.h>
#include <limits.h>
int main() {
unsigned int a = UINT_MAX;
unsigned int b = 2;
// 转换为更宽的类型
unsigned long long result = (unsigned long long)a + b;
// 检查是否超过最大值
if (result > UINT_MAX) {
printf("无符号整数运算发生溢出\n");
} else {
printf("结果为: %u\n", (unsigned int)result);
}
return 0;
}
4、使用编译器工具或内置函数
现代编译器(如 GCC 和 Clang)提供了内置函数来检测溢出。如__builtin_add_overflow
和 __builtin_mul_overflow
是 GCC 的内置函数,可以检测加法和乘法溢出。
#include <stdio.h>
#include <stdbool.h>
int main() {
unsigned int a = UINT_MAX;
unsigned int b = 1;
unsigned int result;
// 使用 GCC 内置函数检测溢出
if (__builtin_add_overflow(a, b, &result)) {
printf("无符号整数加法发生溢出\n");
} else {
printf("结果为: %u\n", result);
}
return 0;
}
5、使用编译器选项检测
某些编译器支持运行时检测整数溢出,如 Clang 的 AddressSanitizer 和 GCC 的 Undefined Behavior Sanitizer,可以检测有符号整数溢出(但无符号整数溢出默认按模处理,不会报错)。