当在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. java网站架构演变过程

    网站架构演变过程. .传统架构.传统的SSH架构,分为三层架构web控制层.业务逻辑层.数据库访问层..传统架构也就是单点应用,就是大家在刚开始初学JavaEE技术的时候SSH架构或者SSM架构,业务 ...

  2. Jenkins+harbor+gitlab+k8s 部署maven项目

    一.概述 maven项目部署流程图如下: 环境介绍 操作系统 ip 角色 版本 ubuntu-16.04.4-server-amd64 192.168.10.122 Jenkins+harbor Je ...

  3. modbus协议使用小记

    下载了libmodbus库,交叉编译后运行,总是接收回复时不正确.原因不明. 由于使用到modbus的需求比较简单,所以选择直接拼出modbus的请求报文,然后用串口直接发送和接收的方式, 拼modb ...

  4. map小列

    // 有关学生信息的头文件student.h代码如下 #include #include using namespace std; struct Student                    ...

  5. Java之路---Day01

    2019-10-17-19:36:43 标识符: 标识符:是指在程序中,自己定义的内容.如:类名.方法名.变量名等 命名规则(硬性要求): 1.有英文字母(区分大小写).数字.$(美元符)._(下划线 ...

  6. 一个多进程爬虫下载图片的demo

    import os,re import pickle import requests import random import time from bs4 import BeautifulSoup f ...

  7. nodeJS从入门到进阶二(网络部分)

    一.网络服务器 1.http状态码 1xx: 表示普通请求,没有特殊含义 2xx:请求成功 200:请求成功 3xx:表示重定向 301 永久重定向 302 临时重定向 303 使用缓存(服务器没有更 ...

  8. JavaScript之控制标签属性

    var pic=document.getElementById('pic'); var obtn=document.getElementById('btn'); console.log(pic.get ...

  9. webpack练手项目之easySlide(一):初探webpack

    最近在学习webpack,正好拿了之前做的一个小组件,图片轮播来做了下练手,让我们一起来初步感受下webpack的神奇魅力.     webpack是一个前端的打包管理工具,大家可以前往:http:/ ...

  10. linux查看log软件

    可以使用LNAV软件查看log,还是比较方便的 安装步骤 $ sudo apt install lnav 获取帮助信息 $ lnav -h 查看日志 $ lnav 查看指定日志(后面加上绝对路径) $ ...