标准C++中整数除零是未定义行为,不抛异常;浮点除零按IEEE 754产生INF或NaN,同样不抛异常;try/catch无法捕获,因硬件触发信号而非C++异常。

除以零在C++里根本不会抛出异常
直接说结论:标准C++中,整数除以零是未定义行为(UB),int a = 5 / 0; 不会触发 std::exception 或任何可捕获的异常;浮点数除以零(如 double x = 1.0 / 0.0;)按IEEE 754规则产生 INF 或 NaN,同样不抛异常。你用 try/catch 包住它,什么也抓不到。
为什么 try/catch 捕不到整数除零
因为底层硬件(x86/x64)遇到整数除零时,会触发 CPU 的 #DE(Divide Error)异常,操作系统通常将其转为信号(Linux/macOS 是 SIGFPE,Windows 是 EXCEPTION_INT_DIVIDE_BY_ZERO),而非 C++ 异常机制。C++ 的异常栈展开和 throw/catch 完全不参与这个过程。
-
std::set_terminate或std::set_unexpected也无济于事——它们只管 C++ 异常,不管信号 - 编译器可能在优化时直接删掉明显除零的代码(比如
return 1/0;),甚至导致编译警告或错误(Clang/GCC 的-Wdivision-by-zero) - 即使你手动 raise
SIGFPE,默认行为是进程终止,不是抛 C++ 异常
实际能用的检测和处理方式
想安全处理除零,只能靠“提前检查 + 信号拦截”或“浮点容错”,没有银弹:
- 对整数运算:永远先判断除数是否为零,再做除法 —— 这是最简单、最可靠、最推荐的做法
if (b != 0) { result = a / b; } else { /* 处理错误 */ } - 对浮点运算:检查结果是否为
std::isinf()或std::isnan(),而不是依赖异常double r = x / y; if (std::isinf(r) || std::isnan(r)) { /* 处理溢出或无效操作 */ } - 需要全局拦截整数除零(如调试或嵌入式监控):注册
SIGFPE信号处理器(Linux/macOS)或结构化异常处理(Windows SEH),但要注意信号处理函数限制多(不能调用大多数标准库函数),且无法从原除法语句继续执行
别被第三方库误导
有些数学库(如某些版本的 Boost.Math)或自定义 wrapper 可能封装了除零检查并主动 throw,但这属于库的额外逻辑,不是语言本身行为。如果你看到某段 C++ 代码成功 catch 到除零异常,那一定是它前面显式做了 if (divisor == 0) throw std::runtime_error("..."); 这类判断,而不是编译器或运行时自动产生的。
立即学习“C++免费学习笔记(深入)”;
真正容易被忽略的是:跨平台时信号名和处理方式不同,SIGFPE 在某些嵌入式系统上可能不可用或行为不一致;而浮点除零的 INF/NaN 传播可能影响后续计算,比崩溃更隐蔽。


















