问题描述
这是一段简单的代码,其中发生了被零除.我试图抓住它:
Here is a simple piece of code where a division by zero occurs. I'm trying to catch it :
#include <iostream>
int main(int argc, char *argv[]) {
int Dividend = 10;
int Divisor = 0;
try {
std::cout << Dividend / Divisor;
} catch(...) {
std::cout << "Error.";
}
return 0;
}
但应用程序无论如何都会崩溃(即使我设置了 MinGW 的选项 -fexceptions
).
But the application crashes anyway (even though I put the option -fexceptions
of MinGW).
是否有可能捕捉到这样的异常(我理解的不是 C++ 异常,而是 FPU 异常)?
Is it possible to catch such an exception (which I understand is not a C++ exception, but a FPU exception) ?
我知道我可以检查除数 before 除数,但我假设,因为除以零很少见(至少在我的应用程序中),它会更多尝试除法(并在发生错误时捕获错误)比在除法之前每次测试除数时有效.
I'm aware that I could check for the divisor before dividing, but I made the assumption that, because a division by zero is rare (at least in my app), it would be more efficient to try dividing (and catching the error if it occurs) than testing each time the divisor before dividing.
我正在一台 WindowsXP 计算机上进行这些测试,但希望让它跨平台.
I'm doing these tests on a WindowsXP computer, but would like to make it cross platform.
推荐答案
也不例外.这是一个错误,在硬件级别确定并返回给操作系统,然后操作系统以某种特定于操作系统的方式通知您的程序(例如,通过杀死过程).
It's not an exception. It's an error which is determined at hardware level and is returned back to the operating system, which then notifies your program in some OS-specific way about it (like, by killing the process).
我相信在这种情况下发生的事情不是例外,而是一个信号.如果是这种情况:操作系统会中断您程序的主控制流并调用信号处理程序,这反过来会终止程序的操作.
I believe that in such case what happens is not an exception but a signal. If it's the case: The operating system interrupts your program's main control flow and calls a signal handler, which - in turn - terminates the operation of your program.
这与取消引用空指针时出现的错误类型相同(然后您的程序因 SIGSEGV 信号而崩溃,分段错误).
It's the same type of error which appears when you dereference a null pointer (then your program crashes by SIGSEGV signal, segmentation fault).
您可以尝试使用 <csignal>
标头中的函数来尝试为 SIGFPE 信号提供自定义处理程序(它用于浮点异常,但也可能是这种情况为整数除以零而引发 - 我在这里真的不确定).但是您应该注意,信号处理是依赖于操作系统的,并且 MinGW 以某种方式模拟"了 Windows 环境下的 POSIX 信号.
You could try to use the functions from <csignal>
header to try to provide a custom handler for the SIGFPE signal (it's for floating point exceptions, but it might be the case that it's also raised for integer division by zero - I'm really unsure here). You should however note that the signal handling is OS-dependent and MinGW somehow "emulates" the POSIX signals under Windows environment.
这是在 MinGW 4.5、Windows 7 上的测试:
Here's the test on MinGW 4.5, Windows 7:
#include <csignal>
#include <iostream>
using namespace std;
void handler(int a) {
cout << "Signal " << a << " here!" << endl;
}
int main() {
signal(SIGFPE, handler);
int a = 1/0;
}
输出:
信号 8 在这里!
在执行信号处理程序后,系统立即终止进程并显示错误消息.
And right after executing the signal handler, the system kills the process and displays an error message.
使用它,您可以在除以零或空指针取消引用后关闭任何资源或记录错误...但 与异常不同,即使在异常情况下也不能控制程序的流程. 一个有效的程序不应该那样做.捕获这些信号仅对调试/诊断有用.
Using this, you can close any resources or log an error after a division by zero or a null pointer dereference... but unlike exceptions that's NOT a way to control your program's flow even in exceptional cases. A valid program shouldn't do that. Catching those signals is only useful for debugging/diagnosing purposes.
(有一些有用的信号通常在低级编程中非常有用,并且不会导致您的程序在处理程序之后立即被杀死,但这是一个很深的话题).
这篇关于C++:捕获除以零错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!