当在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. golang微服务框架go-micro 入门笔记2.1 micro工具之micro api

    micro api micro 功能非常强大,本文将详细阐述micro api 命令行的功能 重要的事情说3次 本文全部代码https://idea.techidea8.com/open/idea.s ...

  2. 配置linux命令行界面的 文件显示颜色

    在linux命令行界面下使用ls命令时,有时会看见显示的文件会有不同的颜色,因为linux的文件没有后缀名这个概念(Windows系统中的文件会有后缀名,从而可以将文件标识为不同类型),显示不同的颜色 ...

  3. Window中C++进行精确计时的方法

    嗯,程序员一个永恒的追求就是性能吧? 为了衡量性能,自然需要计时. 奈何无论C标准库还是C++标准库,因为通用性的考虑,其time API精度都不高.基本都是毫秒级的. 所以如果要真正精确地衡量程序的 ...

  4. Go ---- defer 和 return 执行的先后顺序

    Go 中 defer 和 return 执行的先后顺序 多个defer的执行顺序为“后进先出”: defer.return.返回值三者的执行逻辑应该是:return最先执行,return负责将结果写入 ...

  5. scanf加不加\n?

    近两天用vs2013敲代码碰到的问题 关于scanf小括号中加不加\n的区别 例程序如下所示: 第一个程序: int main(){ ; printf("你会去敲代码吗?(选择1 or 0) ...

  6. 2019 顺网游戏java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.顺网游戏等公司offer,岗位是Java后端开发,因为发展原因最终选择去了顺网游戏,入职一年时间了,也成为了面 ...

  7. crunch制作字典

    安装 安装crunch sudo apt-get install crunch 语法 crunch <min> max<max> <characterset> -t ...

  8. scrapy xpath去除空格

    content = response.xpath("normalize-space('//img/@src')")

  9. c# 泛型study

    1.引用类型约束:  类型实参包含任何类,接口,数组,委托,或者是已知是引用类型的另一个类型参数 class demo<T> where T:class 有效的封闭区间demo<St ...

  10. Kubernetes集群开启Firewall

    关于端口的官方说明:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/ k8s ...