C++为什么抓不到除0错“异常”?
http://blog.csdn.net/nanyu/article/details/6475555
有人问这个问题:
- try
- {
- std::cout << 10/0 << std::endl;
- }
- catch(...)
- {
- std::cout << "exception" << std::endl;
- }
这段代码,永远不会有机会在屏幕上输出 exception。
为什么? 因为和ada或java不一样,C++标准没有把除0错当成标准异常。
上面的代码原样放到VC里,我猜测(基于对VC的基本信任,也基于我的懒惰),VC也不会执行07行代码。VC里要抓这样的异常,需要采用操作系统的结构化异常。它的代码需要使用 __try/__except来处理。或者需要在编译选项上,加上让C++异常支持SEH(结构化异常处理)的参数。
C++之父在谈C++语言设计的书(The Design and Evolution of C++)里谈到:
"low-level events, such as arithmetic overflows and divide by zero, are assumed to be handled by a dedicated lower-level mechanism rather than by exceptions. This enables C++ to match the behaviour of other languages when it comes to arithmetic. It also avoids the problems that occur on heavily pipelined architectures where events such as divide by zero are asynchronous."
简单翻译一下: “底层的事件,比如计算上的溢出和除0错,被认为应用有一个同样底层的机制去处理它们,而不是异常。这让C++在涉及到算术领域的性能,可以和其它语言竞争。再者,它也避免了当某些事件,比如除0错是异步的情况下(译者注:比如在别一个线程里发生)所可能造成的‘管道重重’的架构这一问题。”
所以,说起来,和原生数组访问越界为什么不是一异常并无两样,主要还是为了“效率/性能”。对于大多数时候的除法操作,我们会让它出现除数为0的可能性很小,当你认为有这种可能,就自己检查吧,然后自己定义一个除0错的异常。
很多C++库,还是实现了EDivByZero之类异常,但仅限于这个库里的代码。它们做了检查。
总结一下:C++为什么抓不到除0错的“异常”? 答:因为C++标准眼里,除0错不是一个异常。再进一步:C++编译器,在编译除法操作时,没有为它加上额外的检查代码以抛出一个异常;也没有要求处理不同OS之间对(已经发生的)除0错的处理。
另一个原因是,简单化,比如如果要判断除0错,浮点数如何判断呢?
说到底,在事情发生之前,判断一下不是更好?
- if (b == 0)
- {
- cout << "别玩我啦...拿个0当除数?" << std::endl;
- return -1;
- }
这样不是很好?
https://blog.csdn.net/u012877537/article/details/38231267
C++为什么抓不到除0错“异常”?的更多相关文章
- OAuth2.0 错误码
http://open.taobao.com/doc/detail.htm?id=118 OAuth2.0 错误码 新浪微博OAuth2.0实现中,授权服务器在接收到验证授权请求时,会按照OAuth2 ...
- Unrecognized Windows Sockets error: 0: JVM_Bind 异常怎么办
Unrecognized Windows Sockets error: 0: JVM_Bind 异常解决办法 java.net.SocketException: Unrecognized Window ...
- Flutter中用ListView嵌套GridView报错异常
flutter中的ListView组件和GridView组件都是常用的布局组件,有时候ListView中需要嵌套GridView来使用,例如下图: 这种情况就需要在ListView里面再嵌套一个Gri ...
- Struts2报错异常Method "setUser" failed for object com.mikey.action.ConverterAction@dd34285
在写类型转换的时候发现报错 异常信息 ognl.MethodFailedException: Method "setUser" failed for object com.mike ...
- Mac下抓包工具Charles4.0下载及使用
Charles是一款运行在你自己计算机上的web代理工具,可以有效地获取http通信信息,主要用于网页的开发和调试等. 安装 以下为来自史蒂芬周的博客的Charles 4.0 Mac破解版 下载地址: ...
- selenium抓取淘宝数据报错:warnings.warn('Selenium support for PhantomJS has been deprecated, please use headless
ssh://root@192.168.33.12:22/root/anaconda3/bin/python3 -u /www/python3/maoyantop100/meishi_selenium. ...
- eclipse 和 android studio 编译时报 Unsupported major.minor version 52.0错解决办法
version 52.0 是java8的环境.当gradle tools 升级到2.2.1时候,可能编译时候会报该错误. 很多网友说更改java version,但是很多时候无效.下面是我遇到时候的解 ...
- 安装sybase12.0,运行时报错异常。
报错为:invalid command line argument ' and' 当通过开始菜单打开"配置服务器"时,回报如上异常,当继续创建服务器是,不会成功.实际上不是程序出错 ...
- Android 开发 关于7.0 FileUriExposedException异常 详解
异常原因 Android不再允许在app中把file://Uri暴露给其他app,包括但不局限于通过Intent或ClipData 等方法.原因在于使用file://Uri会有一些风险,比如: 文件是 ...
随机推荐
- Cocos2dx使用ios内支付IAP具体流程-白白
今天总结了一下cocos2d-x使用ios内支付iap的具体流程,封装好了调用接口,代码与具体说明在此 http://download.csdn.net/detail/u010229677/81566 ...
- 获取路由事件的源Source和OriginalSource
路由事件的消息包括在RoutedEventArgs实例中,该实例有两个属性Source和OriginalSource,都是表示路由事件传递的起点.即事件消息的源头.仅仅只是Source表示的是Logi ...
- Lighttpd 插件mod_h264 streaming (mp4)安装
1. 对于安装lighttpd须要支持mp4伪流媒体格式,建议不要到官方下载lighttpd安装文件,到 插件H264 Streaming Module官网,下载已经整合了的安装包 http://h2 ...
- SDUST 2844-Mineral Water(数学)
Mineral Water nid=24#time" title="C.C++.go.haskell.lua.pascal Time Limit1000ms Memory Limi ...
- opencv对图像进行边缘及角点检測
opencv对图像进行边缘及角点检測 先看结果: 代码: // ConsoleApplication1_812.cpp : Defines the entry point for the consol ...
- Android WebView开发常见问题
1.加入权限:AndroidManifest.xml中必须使用许可"android.permission.INTERNET",否则会出Web page not available错 ...
- mybtis 逆向
mbg.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfi ...
- go12---interface
package main /* 接口interface 接口是一个或多个方法签名的集合 只要某个类型拥有该接口的所有方法签名,即算实现该接口,无需显示 声明实现了哪个接口,这称为 Structural ...
- 怎么在当前的view上获取所在的控制器(UIViewController),实现跳转
- (UIViewController *)viewController { for (UIView* next = [self superview]; next; next = next.super ...
- mysql —— 利用Navicat 导出和导入数据库
Navicat for MySql 导出数据库方法: 打开Navicat for MySql,在要导出的数据库上面右击鼠标,点击“转储SQL 文件”→“数据和结构”. 找到合适的路径,点击“保存”. ...