整数除零在c++中不会抛出std::exception,而是未定义行为,导致程序崩溃(如sigfpe);浮点除零按ieee 754返回inf或nan,不抛异常。安全做法是除前检查:整数需判y==0及int_min/-1溢出,浮点需用std::isinf/std::isnan校验结果。

整数除零在 C++ 里不会抛出 std::exception,程序直接崩溃;浮点除零默认不崩溃,但结果是 inf 或 nan。
整数除零:不是异常,是未定义行为
当你写 a / b 且 b == 0(a、b 是 int 等整型),C++ 标准明确这是未定义行为。编译器不会插入检查,运行时也不会 throw 任何异常——Linux/macOS 触发 SIGFPE,Windows 触发 EXCEPTION_INT_DIVIDE_BY_ZERO,进程立刻终止。
常见错误现象:
- 调试器显示
Signal: SIGFPE (Arithmetic exception) -
try { x / y; } catch(...) { }完全无效,根本进不去catch - 加了
-ftrapv或-fsanitize=undefined才能在崩溃时看到清晰提示(如division by zero+ 调用栈)
浮点除零:有定义,但默认不报错
float 或 double 除零按 IEEE 754 标准处理:1.0 / 0.0 得 inf,0.0 / 0.0 得 nan。这不算错误,也不中断执行。
使用场景和注意事项:
- 科学计算中常依赖
inf/nan传播,后续用std::isinf()或std::isnan()过滤 - 若需让浮点除零也触发异常,得手动启用:比如调用
feenableexcept(FE_DIVBYZERO)(POSIX),但 Windows 不支持该 API - 启用后行为跨平台不一致,且可能影响性能,一般只在调试或关键数值验证阶段开启
怎么安全地避免崩溃
唯一可靠方式是「除前检查」,而不是事后捕获。尤其对整数:
- 基础检查:
if (y == 0) - 补码边界必须额外判断:
if (y == 0 || (y == -1 && x == INT_MIN))(否则INT_MIN / -1同样未定义) - 用
std::div前也得自己检查除数,它不校验 - 若逻辑上除数绝不能为零(如配置项、硬件寄存器地址),优先用
assert(y != 0)+ 单元测试覆盖,比运行时兜底更早暴露问题
信号处理 or 异常模拟?慎用
有人试图用 signal(SIGFPE, handler) 捕获整数除零,但实际非常危险:
- Linux 下 handler 内只能调用异步信号安全函数(
write可以,std::cout、malloc、printf全都不行) - Windows 需用 SEH(
__try/__except),API 和语义完全不同 - 多线程中
signal()行为未定义;必须配合pthread_sigmask+sigwait - 即使捕获成功,CPU 寄存器/栈可能已损坏,继续执行风险极高——仅适合记录 crash dump 后退出,不能用于“恢复计算”
真正容易被忽略的点是:整数除零和溢出(如 INT_MIN / -1)崩溃表现一样,但原因不同,检查逻辑必须同时覆盖两者。靠 try/catch 或信号兜底,本质是在掩盖设计缺陷。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











