1.简介

C语言中,如果程序的运行出现异常、错误,我们想提供方案处理这些异常时,我们面临许多问题,如: 
(1)C语言没有提供统一(标准)的方式来处理错误; 
(2)无法保证错误会被正确的处理; 
(3)错误的传播无法控制,特别是在函数的嵌套调用时; 
… …

当程序在运行时发生错误,使得程序的继续运行变得毫无意义时,C++中的异常机制给我们提供了一个解决方法。

2.C++03 异常处理(throw)

C++98中,在函数声明时,我们使用throw指定一个函数可以抛出异常的类型。例如:

class Ex {
public:
double getVal();
void display() throw();
void setVal(int i) throw (char*, double);
private:
int m_val;
};

上述函数的声明指定了该函数可以抛出异常的类型: 
getVal() 可以抛出任何异常(默认); 
display() 不可以抛出任何异常; 
setVal() 只可以抛出char* 和 double类型异常。

从功能上来说,C++98中的异常处理机制完全能满足我们的需要,正确的处理异常。 
然而,编译器为了遵守C++语言标准,在编译时,只检查部分函数的异常规格(exception specification)。 
注: 
exception specification: 函数名字后面的throw表达式,或者noexcept。

// declaration
extern void funAny(void); //May throw ANY exception.
void check(void) throw (std::out_of_range); // May throw only std::out_of_range. // implementation
void check(void) throw(std::out_of_range) {
funAny(); // Compiler does not check if
... // funAny(), or one of its
} // subordinates, only throws std::out_of_range!

程序在运行时,如果funAny()抛出一个异常, 
但是它的类型不是std::out_of_range, 异常处理机制将调用std::unexpected()(该函数自己也可能抛出异常), 
这个函数默认情况下会调用std::teminate().

3.C++11异常处理(noexcept)

编译器在编译时能过做的检测非常有限,因此在C++11中异常声明被简化为以下两种情况: 
(1)函数可以抛出任何异常(和之前的默认情况相同); 
(2)函数不可以抛出任何异常。

在C++11中,声明一个函数不可以抛出任何异常使用关键字noexcept.

void mightThrow(); // could throw any exceptions.
void doesNotThrow() noexcept; // does not throw any exceptions.

下面两个函数声明的异常规格在语义上是相同的,都表示函数不抛出任何异常。

void old_stytle() throw();
void new_style() noexcept;

它们的区别在于程序运行时的行为和编译器优化的结果。 
使用throw(), 如果函数抛出异常,异常处理机制会进行栈回退,寻找(一个或多个)catch语句。 
此时,检测catch可以捕捉的类型,如果没有匹配的类型,std::unexpected()会被调用。 
但是std::unexpected()本身也可能抛出异常。 
如果std::unexpected()抛出的异常对于当前的异常规格是有效的, 
异常传递和栈回退会像以前那样继续进行。 
这意味着,如果使用throw, 编译器几乎没有机会做优化。 
事实上,编译器甚至会让代码变得更臃肿、庞大: 
(1)栈必须被保存在回退表中; 
(2)所有对象的析构函数必须被正确的调用(按照对象构建相反的顺序析构对象); 
(3)编译器可能引入新的传播栅栏(propagation barriers)、引入新的异常表入口,使得异常处理的代码变得更庞大; 
(4)内联函数的异常规格(exception specification)可能无效的。

当使用noexcept时,std::teminate()函数会被立即调用,而不是调用std::unexpected(); 
因此,在异常处理的过程中,编译器不会回退栈,这为编译器的优化提供了更大的空间。

简而言之,如果你知道你的函数绝对不会抛出任何异常,应该使用noexcept, 而不是throw().

原文转自:http://blog.csdn.net/zkreats/article/details/50550786

原作者为 zkreats。请尊重原作者版权

C++11异常处理 noexcept的更多相关文章

  1. Java程序设计11——异常处理

    1 概述 异常机制已经成为判断一门编程语言是否成熟的标准,除了传统的像C语言没有提供异常机制之外,目前主流的编程语言如Java.Ruby.Python都提供了成熟的异常机制.异常机制可以使程序中异常处 ...

  2. Python学习之路11☞异常处理

    一 错误和异常 part1:程序中难免出现错误,而错误分成两种 1.语法错误(这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正) #语法错误示范一 if #语法错误示范二 de ...

  3. Java 学习笔记(11)——异常处理

    异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的. 比如说,你的代码少了一个分号,那么运行出来结果是提示是错误 java.lang.Error:如果你用System.ou ...

  4. J2SE基础:11.异常处理

    1:异常的概念: 异常是程序在执行时发生的事件(异常发生在执行期间). 程序出现错误.打断原本的运行流程. 2:Java中处理异常. 在Java中.异常被封装成一个对象.(属性和方法) 3:异常产生 ...

  5. SpringBoot: 11.异常处理方式1(自定义异常页面)(转)

    SpringBoot 默认的处理异常的机制:SpringBoot 默认的已经提供了一套处理异常的机制.一旦程序中出现了异常 SpringBoot 会向/error 的 url 发送请求.在 sprin ...

  6. noexcept(c++11)

    1.概念 1)c++中的异常处理是在运行时而不是编译时检测的,为了实现运行时检测,编译器可能会创建额外的异常处理代码,然而这会妨碍程序优化 2)noexcept说明符:若修饰函数(紧跟在参数列表后面) ...

  7. c++11 noexcept修饰符

    c++11 noexcept修饰符 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> ...

  8. C++11 noexcept 关键字用法学习

    最近学习和写了一个 mint 的板子 ,其中用到了 noexcept 关键字,对这个关键字不太熟悉,便学习一下刘毅学长的文章. C++98 中的异常规范(Exception Specification ...

  9. C++11 不抛异常的new operator

    在google cpp style guide里面明确指出:we don't use exceptions C++11的noexcept关键字为这种选择提供了便利. C++11以前,提及malloc和 ...

随机推荐

  1. linux下motion摄像头监控编译与配置

    利用linxu下的开源的motion搭建嵌入式视频动态监控系统 所谓移动图像监测,简单来说就是利用摄像头定点监测某个区域,当有移动物体经过时,摄像头便自动抓拍(要监测多大物体.按拍照速率都是可调的), ...

  2. 【4412嵌入式开发板学习笔记】认识uboot

    转自迅为讨论群:http://www.topeetboard.com 重要说明:这份笔记不是4412开发配套的,是我在网上看视频的时候下载上课老师的笔记后修改的.所以我试了一下笔记上的uboot命令, ...

  3. Andorid 6连接Libreswan L2TP VPN

    手机升级到Android 6以后,以前正常使用的L2TP VPN却无法连接了.服务器端日志: "vpnpsk"[119] 114.249.245.192 #240: no acce ...

  4. UVa11549计算器谜题[floyd判圈]

    题意: 有个老式计算器,每次只能记住一个数字的前n位.现在输入一个整数k,然后反复平方,一直做下去,能得到的最大数是多少.例如,n=1,k=6,那么一次显示:6,3,9,1... 白书上的题 set, ...

  5. VS 代码Diff 之Beyone Compare

    前提条件 机器已安装 beyone compared软件和 visual svn for vs 插件. 在VS中集成SVN,我推荐使用 visual svn扩展. visual svn 官网:http ...

  6. Windows 10 UWP开发:如何不让界面卡死

    http://edi.wang/post/2016/2/18/windows-10-uwp-async-await-ui-thread 关于UI线程 这里我们需要一点关于 UI 线程模型的概念,简单的 ...

  7. MyBatis配置文件解析

    MyBatis配置文件解析(概要) 1.configuration:根元素 1.1 properties:定义配置外在化 1.2 settings:一些全局性的配置 1.3 typeAliases:为 ...

  8. Maven学习(九)插件介绍

    我们都知道Maven本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完成,例如编译源代码是由maven-compiler-plugin完成的.进一步说,每个任务对应了 ...

  9. java 22 - 22 多线程之 匿名内部类的方式实现多线程

    首先回顾下之前的匿名内部类: 匿名内部类的格式: new 接口或者接口名(){ 重写方法 }; 本质:是该类或者接口的子类对象 匿名内部类方式使用多线程 1.new Thread(){代码-}.sta ...

  10. Windows 8.1 新增控件之 AppBar

    Windows 8.1 与Windows 8 相比已经有了很多改进,从ITPro 角度这篇文章<What's New in Windows 8.1>已经表述的很详细.对开发者来说,最明显的 ...