当在C++语言中引入异常时,引入了相应的throw(…)动态异常说明符,注释了哪些异常可以由函数抛出。比如:

// this function might throw an integer or a pointer to char,
// but nothing else.
void foo() throw(int, char*);

这让很多人非常愤怒,并被普遍认为是一个糟糕的举动。

根据C++ 98标准,如果函数抛出了未在其动态异常说明符中指定的类型中列出的异常, 系统调用了std::unexpected()函数,std::unexpected()的默认行为是通过调用std::terminate()来终止程序。作为特殊情况,throw()意味着函数根本不应该抛出任何异常。
在C++ 11标准里,放弃了throw(…)动态异常说明符,并且在C++ 17中,除了throw()的特殊情况之外,所有对动态异常说明符的支持都被删除。 同时,改变了当你说你不会的时候抛出异常的惩罚:运行时直接调用std::terminate(),而不是通过std::unexpected()。
当然,微软C++编译器必须做一些不同的事情。

微软C++编译器将throw(…)异常说明符视为程序员的一个允诺,但没有强制执行。它相信你会遵守你自己强加的合同。如果在函数承诺不抛出异常时抛出异常,则行为是未定义的。如果函数说可以抛出一些异常,编译器不会验证是否允许实际抛出的异常;它只是传播异常。实际上,发生的情况是编译器在假定不会引发不允许的异常的情况下执行优化。最常见的这种优化是,编译器不必为它“知道”永远不需要展开的事情注册展开代码,因为在对象销毁之前,没有可能抛出异常的点。

void Example()
{
ObjectWithDestructor obj;
obj.stuff_that_does_not_throw();
// destructor runs here
}

如果stuff_that_does_not_throw被标记为不抛出,那么编译器可以避免在异常传播期间注册obj进行展开,因为您承诺任何异常都不能逃逸。然后抛出异常并使所有优化无效。最常见的可见效果是,从不应该让异常转义的函数传播的异常,以及某些对象析构函数无法运行。

但是等等,一切都没有失去。如果启用/std:c++17,那么微软C++编译器将实现throw(…)的标准行为。

是的,到那儿花了很长时间,但迟到总比不到好。

悲伤的 C++ throw(…)的更多相关文章

  1. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  2. C++异常处理:try,catch,throw,finally的用法

    写在前面 所谓异常处理,即让一个程序运行时遇到自己无法处理的错误时抛出一个异常,希望调用者可以发现处理问题. 异常处理的基本思想是简化程序的错误代码,为程序键壮性提供一个标准检测机制. 也许我们已经使 ...

  3. java中的throw与throws的区别

    什么时运行时异常?什么是非运行时异常? 通俗的讲: 运行时异常:就是编译通过,运行时就崩了,比如数组越界. 非运行时异常:就是编译不通过,这时就得必须去处理了.不然就没法运行了. 全面的讲: Thro ...

  4. js 利用throw 写的一个小程序

    在下边的小程序中比较特殊的是使用isNaN()函数判断一个参数是不是数字, <!DOCTYPE html> <!DOCTYPE html> <html> <h ...

  5. C++异常处理: try,catch,throw,finally的用法

    写在前面 所谓异常处理,即让一个程序运行时遇到自己无法处理的错误时抛出一个异常,希望调用者可以发现处理问题. 异常处理的基本思想是简化程序的错误代码,为程序键壮性提供一个标准检测机制. 也许我们已经使 ...

  6. Java 中 手动抛出异常: throw new Exception("错误信息") 错误信息的获得

    当然需要先用try catch捕获,但注意new Exception("")括号里的字符串其实是异常原因,所以获取是要用ex.getCause().getMessage() int ...

  7. throw exception

    Throw new CustomerException('Customer message'); // App\Exceptions\Handler.php public function rende ...

  8. try{}、catch(){}、throw语句

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  9. C#中异常:“The type initializer to throw an exception(类型初始值设定项引发异常)”的简单分析与解决方法

    对于C#中异常:“The type initializer to throw an exception(类型初始值设定项引发异常)”的简单分析,目前本人分析两种情况,如下: 情况一: 借鉴麒麟.NET ...

随机推荐

  1. SQL Server日志处理及安全访问

    1.点SQL SERVER错误日志,右键,配置,限定错误日志的数目,比如6个 限制日志增长数量 2.然后运行命令: EXEC sp_cycle_errorlog ; 这个命令的作用是将当前日志归档,然 ...

  2. 工信部要求应用商店上新 App 检查 IPv6,这里有一份 IPv6 快速部署指南

    7 月 25 日,工业和信息化部信息通信发展司组织召开部署推进 IPv6 网络就绪专项行动电视电话会议.会议指出,加快推进 IPv6 规模部署,构建高速率.广普及.全覆盖.智能化的下一代互联网,是互联 ...

  3. zbar android sdk源码编译

    zbar,解析条码和二维码的又一利器,zbar代码是用c语言编写的,如果想在Android下使用zbar类库,就需要使用NDK将zbar编译成.so加载使用,zbar编译好的Android SDK可以 ...

  4. CentOS7 安装 Docker、最佳Docker学习文档

    目录 一.Docker支持 二.安装Docker -1.在新主机上首次安装Docker CE之前,需要设置Docker存储库.之后,就可以从存储库安装和更新Docker. 0.卸载旧版 1.正式安装 ...

  5. 处女篇:自用C#后端SqlHelper.cs类

    自用SqlHelper.cs类,此类来自软谋教育徐老师课程SqlHelper.cs! using System; using System.Collections; using System.Coll ...

  6. Kafka 系列(一)—— Kafka 简介

    一.简介 ApacheKafka 是一个分布式的流处理平台.它具有以下特点: 支持消息的发布和订阅,类似于 RabbtMQ.ActiveMQ 等消息队列: 支持数据实时处理: 能保证消息的可靠性投递: ...

  7. Java数据结构-ArrayList最细致的解析笔记

    ArrayList是一个类,这个类有一个数组参数elementData,ArrayList集合中的元素正是保存在这个数组中,它继承了数组查询的高性能,参考第3篇.ArrayList还封装了很多方法,便 ...

  8. IE浏览器 location.href 不跳转

    var url = "https://www.cnblogs.com/zing"; location.href = url; window.event.returnValue = ...

  9. NIO开发Http服务器(5-完结):HttpServer服务器类

    最近学习了Java NIO技术,觉得不能再去写一些Hello World的学习demo了,而且也不想再像学习IO时那样编写一个控制台(或者带界面)聊天室.我们是做WEB开发的,整天围着tomcat.n ...

  10. mac上使用git命令上传项目工程源码至Github/gitee

    原文连接:(http://www.studyshare.cn/blog/details/1164/0 ) 一.安装git工具 1.官网下载地址:点击下载  安装步骤略,mac安装工具双击拖动即可. 2 ...