问题来源于《数据结构、算法与应用C++描述》一书中 1.3 异常 中的程序1-8和程序1-9。
0·throw抛出异常后怎么处理。
0·1·小方框右上角有一个绿色倒三角▲(继续执行)
这个小方框报出的异常是可以继续执行的。你可以理解为编译器没有经过调教而主动弹出异常,作为一个提醒,然后需要你手动点击继续;等调教过后就不会弹出异常了,它会自动跳过。(往后看)
1·调教编译器(
代码1:
//程序1-8
#include <iostream>
using namespace std;
#include <stdlib.h>
int abc(int a, int b, int c) {
if (a <= 0 || b <= 0 || c <= 0) {
throw "All parameters should be > 0";
}
return (a + b * c);
}
//程序1-9
int main() {
double z = 0;
try {
cout << abc(2, 0, 1) << endl;
}
catch (/*const */char* e) {
cout << "The parameters to abc were 2,0,and 4" << endl;
cout << "An exception has been thrown" << endl;
cout << e << endl;
return 1;
}
return 0;
}
代码如上↑↑↑
结果如下↓↓↓(错误结果)1·1·在查找解决方案的时候试过了很多,如链接一给出的:命令行添加/EHa。可惜的是,命令行根本没法输入;即便底部的编辑栏可以输入,但仍然无效。
顺着/EHa可以查到链接二里的方法。
连接一: vs开发,添加try catch(...)发现没有捕获异常,需要对编译命令进行设置_vs 2019 c++ try catch 无效-优快云博客
链接二:vs中/EHa、/EHs、/EHsc的区别_ehsc eha-优快云博客
可惜的是依旧没有用。
1·2·问题出在哪?这个问题这么小众吗?我想过会不会是vs2022版本较新,不支持try-catch了。好家伙,考古到了06年的残卷。又有新思路了——编译器优化的原因。
链接三:求救:try{}catch(...){} 在 Release 版本下失效-优快云社区
1·3·如果我换一个函数,编译器也会优化吗?(除数为零)
链接四:C++ 异常处理 | 菜鸟教程
代码2:
#include <iostream>
using namespace std;
double division(int a, int b)
{
if (b == 0)
{
throw "Division by zero condition!";
}
return (a / b);
}
int main()
{
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << z << endl;
}
catch (const char* msg) {
cerr << msg << endl;
}
return 0;
}
此时你会发现,代码1和代码2的throw后跟的同样是字符串,代码2中的catch(const char* msg)与catch(char* e)不完全一样。
结果是:代码2能够正常抛出异常,代码1不能。这说明throw "Division by zero conditionS";双引号里的内容是const char* 型。
原因:const char* msg是指向常量的指针;char* e是指向变量的指针。(参考链接五)
链接五:char *与const char* 的区别_const char*和char*的区别-优快云博客
1·4·至此已经能得到预期的结果了。但还有一个小问题,就是能不能让编译器跳过上面左图弹出异常、点击继续这一步,直接给出上面右图结果呢?当然可以。
当编译器抛出异常时,将最下面KernelBase.dll勾选上就行了。这样点击运行后,便会直接给出运行结果,也即catch块的内容。
2·小结
1·4·这一步,我感觉有点多余,因为可以把抛出异常导致的程序暂停是正常暂停,不是非正常暂停,也不是程序终止。暂停告诉你程序出错,不然为什么叫:抛出异常呢。
但是但是,话又说回来,怎么给我抛到return 上了???我总以为是格式不规范导致的。。。如果你正常暂停我就知道错误处在哪里的话,那我还要catch()块干什么?所以还是别中途抛出异常好了。