未捕获整数除零异常

时间:2014-10-11 13:14:16

标签: visual-c++ exception-handling seh

我一直在阅读 Teach Yourself C++ In 21 Days , by Jesse Liberty 这本书,并遇到了异常和错误一章。作者使用这个例子:

int top = 10;
int bottom = 0;
try
{
    cout << "top divided by bottom = ";
    cout << (top / bottom) << endl;
}
catch(...)
{
    cout << "something has gone wrong!" << endl;
}

它适用于他。捕获异常并输出:

top divided by bottom = something has gone wrong!

我自己尝试过并收到以下错误:

Unhandled exception at 0x0124152d in stuff.exe: 0xC0000094: Integer division by zero.

integer division by zero

根据this thread,&#34;整数除零在标准C ++中不是例外。&#34;但Visual Studio显然在这里抛出一个异常,虽然没有抓住它。

我尝试将topbottom定义为double,我收到了以下输出:

top divided by bottom = 1.#INF

那么为什么try catch块没有捕获integer division by zero例外?

2 个答案:

答案 0 :(得分:4)

Use /EHa to switch the exception-handling model,因此try - catch可以捕获非C ++异常。

请注意,如果您这样做,所有异步异常都将转换为同步,并且您真的不想抓到最多。
因此,不推荐用于一般代码

顺便说一句,盲目地抓住你所能做到的只是一种已知的反模式,只能抓住你真正期望和能够处理的东西。

请参阅此处了解__try - __except,它始终可以捕获异步异常:http://msdn.microsoft.com/en-us/library/s58ftw19.aspx

答案 1 :(得分:2)

这本书可能会被忽略告诉你,你必须使用/ EHa进行编译。默认值为/ EHsc,它不会导致catch(...)捕获这些SEH异常。

抓住(...)抓住一切并不是很漂亮。你不希望这种情况发生:

int* p = 0;
try {
    int result = *p / 0;
    std::cout << result << std::endl;
}
catch (...) {
    std::cout << "Division by zero" << std::endl;
}

实际上并非零故障,当然不好。更好的鼠标陷阱是将SEH异常转换为C ++异常。您可以通过安装在发生SEH异常时运行的回调来执行此操作,如下所示:

#include <exception>
#include <eh.h>
#include <iostream>

class divisionbyzero_exception : public std::runtime_error {
public:
    divisionbyzero_exception() : std::runtime_error("Division by zero") {}
};

void translate_seh_exception(unsigned int exceptioncode, struct _EXCEPTION_POINTERS* pExp) {
    if (exceptioncode == 0xc0000094) throw divisionbyzero_exception();
}

int main(int argc, char* argv[])
{
    _set_se_translator(translate_seh_exception);
    try {
        int result = argc / 0;
        std::cout << result << std::endl;
    }
    catch (divisionbyzero_exception& ex) {
        std::cout << ex.what() << std::endl;
    }
    return 0;
}

请记住,这完全不可移植。