我一直在阅读 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.
根据this thread,&#34;整数除零在标准C ++中不是例外。&#34;但Visual Studio显然在这里抛出一个异常,虽然没有抓住它。
我尝试将top
和bottom
定义为double
,我收到了以下输出:
top divided by bottom = 1.#INF
那么为什么try catch
块没有捕获integer division by zero
例外?
答案 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;
}
请记住,这完全不可移植。