1.关于结构化异常和C++异常

vs 上,对于C++应用有两种异常,一种是硬件异常,也叫C异常,结构化异常(structured exception)或者异步异常,如访问了无效地址,整数除0等,常见的异常代码是EXCEPTION_ACCESS_VIOLATIONEXCEPTION_STACK_OVERFLOWEXCEPTION_INT_DIVIDE_BY_ZERO。硬件异常一般用__try __except __finally来进行捕获处理。另一种是软件异常,也叫C++异常,同步异常。用try catch throw来处理,一般是调用系统API RaiseException引发的。vs实际上是用SEH(Structured exception handling)来统一实现的。结构化异常是由编译器内部处理的,而C++异常需要我们自己抛出自己处理。
__try __except __finally也可以捕获到C++throw出的异常。

2./EHa、/EHs

EH是 Exception Handling的缩写,这实际上指的是两种SEH异常处理模型。在项目上右击打开属性页,C/C++=》代码生成,
我们可以通过改变这个配置来改变异常处理模型。

2.1.catch(…)捕获区别

/EHa能让catch(…)捕获到结构化异常,而/EHs不能,只能捕获到C++异常。
输入以下代码:

int _tmain(int argc, _TCHAR* argv[])
{try{int a = 0;int b = 2 / a;cout << "b=" << b<<endl;}catch (...){cout << "exception catch" << endl;}system("pause");
}

运行后,假如是/EHs的话,会出现异常对话框,

就算点继续它还会再打开,而且运行生成的exe文件会崩溃。

如果是/EHa的话,不弹异常对话框,输出:

而且运行exe文件也不会崩溃,说明异常是得到捕获处理的,后面的代码能接着运行。

2.2.异常触发的时候局部对象是否有调用析构函数

/EHa能在异常触发的时候,让局部对象的析构函数能被调用,无论是结构化异常还是C++异常的触发。而/EHs只能在触发C++异常的时候才保证局部对象的析构函数被调用,结构化异常的时候不会,这就造成了内存泄露。
输入以下程序:

#include <excpt.h>
#include <exception>class TestClass
{public:~TestClass(){printf("Destroying TestClass!\r\n");}
};void TestExceptions(){TestClass ts;
#ifdef CPPEXcout<<("Throwing C++ exception\r\n");throw exception("c++ exception");
#elsecout<<("Triggering SEH exception\r\n");int a = 0;int b = 2 / a;cout << "b=" << b << endl;
#endif // CPPEX
}int _tmain(int argc, _TCHAR* argv[])
{__try{TestExceptions();}__except (EXCEPTION_EXECUTE_HANDLER){cout<<("Executing SEH __except block\r\n");}system("pause");
}

2.2.1.当为/EHa的时候:

定义了CPPEX,输出为:

没定义CPPEX的时候,输出为:

可见析构函数都被调用了。

2.2.2.当为/EHs的时候:

定义了CPPEX,输出为:

没定义CPPEX的时候,输出为:

可见只有C++异常的时候才会调用析构函数。

3./EHs、/EHsc

(此部分是在Release下进行的)
/EHsc实际上是/EHs和/EHc的组合,当有/EHs假设extern "C"修饰的函数可能会抛出C++异常,而/EHsc假设extern "C"修饰的函数不抛出C++异常,其他跟/EHs一样。
输入以下代码:

#include <exception>
extern "C" void doPrint(){cout << __FUNCTION__ << endl;throw exception("doPrint exception");}int _tmain(int argc, _TCHAR* argv[])
{try{doPrint();}catch (const exception &e){cout << e.what() << endl;}system("pause");
}

运行程序,/EHsc的时候,会出现异常对话框,

就算按继续也会继续弹出来。输出如下:

当为/EHs的时候,不弹异常对话框,输出:

这是因为/EHsc假设doPrint函数是不会抛出C++异常的,所以当它抛出C++异常,而且没在内部进行处理的时候,并不会将异常在调用栈上进行传递。
不知道为什么Debug下不会弹异常对话框,Release下才会。

4.总结

/EHa能让catch(…)捕获结构化异常,能保证结构化异常或者C++异常发生的时候局部对象的析构函数被调用,而且假设extern "C"函数可能会抛出C++异常。
/EHs无法让catch(…)捕获结构化异常,而且只能保证C++异常抛出的时候局部对象的析构函数被调用,而且假设extern "C"函数可能会抛出C++异常。
/EHsc无法让catch(…)捕获结构化异常,而且只能保证C++异常抛出的时候局部对象的析构函数被调用,而且假设extern "C"函数不会抛出C++异常。

5.默认设置


当这么设置的时候,实际上用的是默认设置。它支持catch(…)捕获结构化异常,但是无论是结构化异常还是C++异常它都不会调用局部对象的析构函数,而且假设extern "C"函数不会抛出C++异常。

ps:我对这也是一知半解,只做参考,有错请指出来。

参考文章:
1.Structured Exception Handling (C/C++)
2./EH (Exception handling model)
3.C++捕获除0和空指针异常
4.关于SEH的简单总结
5.深入解析结构化异常处理(SEH)
6.C++使用try,catch在VS2015中捕获异常
7.try catch为什么没有捕获到除0异常

vs中/EHa、/EHs、/EHsc的区别相关推荐

  1. python中break和continue的区别

    python中break和continue的区别 break 结束for 或者while 循环  后面还没循环到的 不再循环 continue 当满足某种条件时结束当前值的循环 后面没有循环的继续循环 ...

  2. java中separator_java - File.separator和路径中的斜杠之间的区别

    java - File.separator和路径中的斜杠之间的区别 在Java Path-String中使用/和普通的File.separator有什么区别? 与双反斜杠相比,/平台独立似乎不是原因, ...

  3. PHP中self和static的区别,php中self与static的区别

    原文链接,猛击这里. php中self与static的区别 通过一些示例,我们可以很容易看出self和static的区别.假定我们有class Car – 它有两个方法,model和getModel. ...

  4. php 抽象类 接口 区别,PHP中抽象类、接口的区别与选择分析

    本文实例分析了PHP中抽象类.接口的区别与选择.分享给大家供大家参考,具体如下: 区别: 1.对接口的使用是通过关键字implements.对抽象类的使用是通过关键字extends.当然接口也可以通过 ...

  5. php $this self,php中self与$this的区别

    学习php中self与$this的区别. 先来看下parent与self的例子: /* * parent与self的区别 * by www.jbxue.com */ class A{ function ...

  6. mysql中char与varchar的区别分析(补充一句,int和integer没区别)

    转自:http://www.jb51.net/article/23575.htm 在mysql教程中char与varchar的区别呢,都是用来存储字符串的,只是他们的保存方式不一样罢了,char有固定 ...

  7. python中bytearray和java中byte[]的区别_Python经典面试题:说说Python中xrange和range的区别?...

    昨晚一小伙后台问xrange和range有啥区别,讲了下他倒领悟的挺快,其实这也是你各面试Python岗位,经常会遇到的Python面试题,长个心眼哈,说不定明年3月你找工作就用上了. 废话不多说,开 ...

  8. python中函数和方法的区别?Python编程判断当前获取的对象是函数还是方法

    python中函数和方法的区别?Python编程判断当前获取的对象是函数还是方法 目录

  9. SQL中where与having的区别

    SQL中where与having的区别 目录 SQL中where与having的区别 创建表 插入数据 进行聚合操作 # WHERE是在聚合之前进行数据行的过滤而HAVING实在聚合之后进行新数据的过 ...

  10. mysql''和null,mysql中NULL和null的区别

    接触php的web开发一段时间了,在进行数据库操作的时候经常会遇到一个问题,使得同一字段在页面显示时有3种类型NULL,null以及数字,当时的解决办法是将这一字段定义为varchar类型,在插入数据 ...

最新文章

  1. 职场新人成功修炼五诀 迅速在职场占一席之地
  2. mysql ubb html_UBB中轻松实现歌词同步播放_html
  3. MySQL Table--独立表空间
  4. SAP CRM 和 SAP Cloud for Customer 的表格列项目宽度调整的原理介绍
  5. rust怎么拆除墙壁指令_拆除墙体前准备:区分承重墙与非承重墙,拆错影响整栋楼房...
  6. 利用反射判断初始化后的对象所有属性是否为空判断对象指定属性是否为空
  7. 为了和互联网公司抢程序员,这家世界 500 强也是蛮拼的
  8. java编辑遗忘曲线代码,java8的新特性 - 天使broken的个人空间 - OSCHINA - 中文开源技术交流社区...
  9. 手机上有没有学python的软件-【Learn Python】用手机学Python
  10. UIPickView的基本使用
  11. 杨澜给80后女孩子的14个忠告
  12. mysql中 show index from tb_name命令各列的含义
  13. 关于常用STM32F103芯片型号代码
  14. 深入理解JVM虚拟机笔记——类加载机制
  15. python中平方_python里平方
  16. 《非凡的公主希瑞》(She-Ra Princess of Power)[93集全][数码修复][国英双语][RMVB]
  17. 成大事必备的九种办法与能力
  18. 查询国际学术会议的信息
  19. mysql 编程 备份_mysql 容灾备份
  20. 关于dijkstra算法的个人总结

热门文章

  1. 信息学奥赛 CSP-J2 CSP-S2第2轮 复赛 如何取得好成绩
  2. 研究记录02—EKF_SLAM ——2012.4 Joan Sola
  3. 轻松解决网络广播风暴
  4. SpringCloudStream整合Kafka,解决两个通道对应同一个topic报错问题。
  5. 对初学者的React Hooks-关于useState和useEffect的大脑友好指南
  6. [高通SDM450][Android9.0]默认取消dm-verity以及解决OTA校验vbmeta失败问题
  7. Python爬虫实战:爬取淘女郎照片
  8. 谁才是美元数字化的推手
  9. 文化与科技的交织,华为P50 Pro与一曲长城谣
  10. 【光学】基于matlab涡旋光产生【含Matlab源码 1927期】