一直以来,我对c++的异常捕获功能非常困惑。
因为网上几乎99%的关于c++异常捕获的文章给我的感觉就是:
c++异常捕获很简单的啦~就是下面这样嘛,如下
情景1:
try
{
int a = 5, b = 0, c = 0;
c = a / b; // 这里异常
}
catch(...) // 捕获所有异常
{
printf_s("Do not do this!\n");
}
情景2:
try
{
int a = 5, b = 0, c = 0;
if (b == 0) throw "Error: Divided by zero!";
c = a / b; // 这里异常
}
catch(char *str) // 捕获所有异常
{
printf_s("%s\n", str);
}
情景3:
使用标准异常类
try { int* myarray= new int[100000]; } catch (exception& e) { cout << "Standard exception: " << e.what() << endl; }
情景4:
高级一点的,使用自定义的异常类
//可以自己定义Exception class myexception: public exception { virtual const char* what() const throw() { return "My exception happened"; } }myex; int main () { try { if(true) //如果,则抛出异常; throw myex; } catch (exception& e) { cout << e.what() << endl; } return 0; }
今天突然对c++异常捕获感兴趣,然后就在网上进行了大量搜索,搜索目标大概就是百度、优快云和Microsoft网站上相关文档。
搜索到的文章内容基本上如上所述,看得我一头雾水。并不是说以上代码有什么问题,只是单纯靠这几行代码可能并不能达到预期效果。因为我是菜鸟,一直不太注重异常捕获和异常处理,对异常捕获这一块更是没怎么用过,而且我天真的以为只要认真写代码就不会有很大的问题,事实证明这确实是一个很天真的想法。
上面的代码我都能看懂,也知道他们的意思,我也觉得“哇,这么简单?”
可是,当我在VS上新建一个工程,把 情景1 的代码写上去然后 F5 后,发生的事情并不是我想象的那样,“Do not do this!" 并没有输出。
好困惑!!!不是说把异常代码写到 try 就能 catch 到吗?为什么没有呢?骗子!!!
那到底是为什么呢?
经过我再次大量搜索,发现了看似很关键的信息,说要修改项目配置,修改步骤如下:
项目->属性->配置属性->C/C++->代码生成,”启用C++异常“选项修改为 /EHa
我设置好之后再运行,发现在 debug 模式的时候是捕获成功了,但 release 模式的时候捕获失败。
然后,我写另外一段代码:
try
{
int *p = NULL;
*p = 1; // 这里异常
}
catch(...) // 捕获所有异常
{
printf_s("Do not do this!\n");
}
运行后,发现 debug 和 release 模式都能捕获到,输出了“Do not do this!"
对于情景2,我也感觉很困惑。既然要用 if 来判断除数 b 是否为 0,为什么还要 throw 然后到 catch 里面处理?直接在 if 后面处理不好吗?难道是为了自定义异常类统一管理这些异常的处理?
还有一点,只要用了 throw 不管“启用c++异常”设置为什么都会 catch 到 throw 抛出的异常。这一点好理解,这是属于你主动(或者是强制)让它抛出的异常。不知道这样理解对不对,本人小菜鸟一个,不对请留言。
从以上所述可以得出结论:
1、在VS中写代码,c++的try-catch要捕获到“除数为0”和“使用NULL指针”,需要将“启用c++异常”设置为 /EHa;
2、“除数为0”和“使用NULL指针”这两种异常的区别导致c++的try-catch捕获的结果不一样;
3、debug和release两种模式对c++的try-catch也是有影响的;
4、在 try 中用 throw 抛出异常是一定可以捕获到的;
困惑:
1、为什么“除数为0”的异常在 debug 模式的时候是捕获成功了,但 release 模式的时候却捕获失败了?
2、在同样的配置下,是什么原因导致“除数为0”和“使用NULL指针”这两种异常的捕获结果不一样的?
3、throw 到底是为何而设计的?
哪位大神来讨论一下上述问题,或者能解答我上述困惑欢迎留言,谢谢了!!
参考链接:
https://docs.microsoft.com/zh-cn/cpp/cpp/try-throw-and-catch-statements-cpp
https://zhidao.baidu.com/question/263926694.html
https://blog.youkuaiyun.com/woshiyuanlei/article/details/51075020