没有合适的资源?快使用搜索试试~ 我知道了~
C++异常机制的实现方式和开销分析
4星 · 超过85%的资源 需积分: 14 52 下载量 83 浏览量
2012-01-02
03:22:20
上传
评论 1
收藏 453KB PDF 举报
温馨提示
试读
13页
C++异常机制的实现方式和开销分析 一篇深度分析C++异常实现的文章(语言级别分析,没有深入过多的汇编和提供级别)
资源推荐
资源详情
资源评论
@Enic ErrorCpp@gmail (整理稿,
来源不明非原创
在我几年前开始写《C++
编码规范与指导
到时隔几年以后才有机会把这个尾巴补完
还是那句开场白:“
在恰当的场合使用恰当的特性
就必须要了解语言中每个特性的实现方式及其时空开销
中较难理解和透彻掌握的部分。
本文将在尽量少引入底层细节的前提下
销。
关于线程
关于线程关于线程
关于线程
进程和线程的概念相信各位看官早已耳熟能详
•
一个进程中可以同时包含多个线程
。
•
我们通常认为线程是操作系统可识别的最小并发执行和调度单位
Kernel
不认识也不参与这些物件的调度
•
同一进程中的多个线程共享代码段
(
己的栈段
己的栈段己的栈段
己的栈段。栈段又叫运行时栈,
用来存放所有局部变量和临时变量
中的某些概念来说是非常重要的 。
但是请注意
作系统可能不使用段式存储。
不过没关系
终是成立的。
•
由于共享了除栈以外的所有内存地址段
提供一种称为 TLS(
Thread Local Storage
常是线程控制块(TCB)
中的某个指针所指向
由使用者定义,可以指向任意位置
(
函数的调用和返回
函数的调用和返回函数的调用和返回
函数的调用和返回
接着我们来回顾下一个预备知识:
编译器如何实现函数的调用和返回
架(Stack Frame)。“栈框架”
担负着以下重要任务
•
传递参数:通常,
函数的调用参数总是在这个函数栈框架的最顶端
•
传递返回地址:告诉被调用者的
return
•
存放调用者的当前栈指针:
便于清理被调用者的所有局部变量
来源不明非原创
)
编码规范与指导
》一文时,就已经规划着要加入这样一篇讨论
C++
到时隔几年以后才有机会把这个尾巴补完
:-)。
在恰当的场合使用恰当的特性
” 对每个称职的 C++
程序员来说都是一个基本标准
就必须要了解语言中每个特性的实现方式及其时空开销
。异常处理由于涉及大量底层内容
,
本文将在尽量少引入底层细节的前提下
,讨论 C++
中这一崭新特性
进程和线程的概念相信各位看官早已耳熟能详
。在这里,我只想带大家回忆几点重要概念:
。
我们通常认为线程是操作系统可识别的最小并发执行和调度单位
(不要跟俺说还有
Green Thread
不认识也不参与这些物件的调度
)。
(
代码和常量)、数据段(静态和全局变量)和扩展段(
堆存储
用来存放所有局部变量和临时变量
(参数、返回值、
临时构造的变量等
但是请注意
,这里提到的各个“段”都是逻辑上的说法,
在物理上某些硬件架构或者操
不过没关系
,
编译器会保证这些逻辑概念和假设的前提条件对每个
由于共享了除栈以外的所有内存地址段
,线程不可以有自己的“静态”或“全局”变量,
为了弥补这一缺憾
Thread Local Storage
,即:“线程本地存储”)的机制。
通过该机制可以实现类似的功能
中的某个指针所指向
的一个指针数组,
数组中的每个元素称为一个槽
(
但通常是指向堆存储中的某个偏移)。
编译器如何实现函数的调用和返回
。一般来说,
编译器会为当前调用栈里的每个函数建立一个栈框
担负着以下重要任务
:
函数的调用参数总是在这个函数栈框架的最顶端
。
return
语句应该 return 到哪里去,
通常指向该函数调用的下一条语句
便于清理被调用者的所有局部变量
、并恢复调用者的现场。
1 / 13
C++
异常机制的文章了。没想
程序员来说都是一个基本标准
。想要做到这点,
,
向来是 C++ 各种高级机制
中这一崭新特性
,并分析其实现开
Green Thread
或者 Fiber,OS
堆存储
),但是每个线程有自
每个线程有自每个线程有自
每个线程有自
临时构造的变量等
)。这一条对下文
在物理上某些硬件架构或者操
编译器会保证这些逻辑概念和假设的前提条件对每个
C/C++ 程序员来说始
为了弥补这一缺憾
,操作系统通常会
通过该机制可以实现类似的功能
。TLS 通
数组中的每个元素称为一个槽
(Slot),每个槽中的指针
编译器会为当前调用栈里的每个函数建立一个栈框
通常指向该函数调用的下一条语句
(代码段中的偏移)。
@Enic ErrorCpp@gmail (整理稿,来源不明非原创)
2 / 13
•
存放当前函数内的所有局部变量:记得吗?刚才说过所有局部和临时变量都是存储在栈上的。
最后再复习一点:栈是一种“后进先出”(LIFO)的数据结构,不过实际上大部分栈的实现都支持随机访问。
下面我们来看个具体例子:
假设有 FuncA、FuncB 和 FuncC 三个函数,每个函数均接收两个整形值作为其参数。在某线程上的某一时间段内,
FuncA 调用了 FuncB,而 FuncB 又调用了 FuncC。则,它们的栈框架看起来应该像这样:
图 1 函数调用栈框架示例
正如上图所示的那样,随着函数被逐级调用,编译器会为每一个函数建立自己的栈框架,栈空间逐渐消耗。随着函数的
@Enic ErrorCpp@gmail (整理稿,
来源不明非原创
逐级返回,
该函数的栈框架也将被逐级销毁
决于运行时栈空间的剩余尺寸。
这里顺便解释另一个术语:调用约定(
calling convention
器中)的顺序,以及返回时由谁(
调用者还是被调用者
最后再说一句,
这里所展示的函数调用乃是最
个内联甚至非内联的函数生成栈框架,
编译器可能使用很多优化技术消除这个构造
达到这样的理解程度通常就足够了。
C++ 函数的调用和返回
函数的调用和返回函数的调用和返回
函数的调用和返回
首先澄清一点,这里说的 “C++ 函数”是指
:
•
该函数可能会直接或间接地抛出一个异常
使用“throw()”异常过滤器。
•
或者该函数的定义内使用了 try 块。
以上两者满足其一即可。
为了能够成功地捕获异常和正确地完成栈回退
的数据结构和相应的处理机制。
我们首先来看看引入了异常处理机制的栈框架大概是什么样子
来源不明非原创
)
该函数的栈框架也将被逐级销毁
,栈空间得以逐步释放。顺便说一句,
递归函数的嵌套调用深度通常也是取
calling convention
)。调用约定
调用约定调用约定
调用约定通常指:
调用者将参数压入栈中
调用者还是被调用者
)来清
理这些参数等细节规程方面的约定
这里所展示的函数调用乃是最
“经典”的方式。实际情况是:
在开启了优化选项后
编译器可能使用很多优化技术消除这个构造
。
不过对于一个
:
该函数可能会直接或间接地抛出一个异常
:即该函数的定义存放在一个 C++ 编译(
而不是传统
为了能够成功地捕获异常和正确地完成栈回退
(stack unwind
),
我们首先来看看引入了异常处理机制的栈框架大概是什么样子
3 / 13
递归函数的嵌套调用深度通常也是取
调用者将参数压入栈中
(或放入寄存
理这些参数等细节规程方面的约定
。
在开启了优化选项后
,编译器可能不会为一
不过对于一个
C/C++ 程序员来说,
而不是传统
C)单元内,并且该函数没有
),
编译器必须要引入一些额外
我们首先来看看引入了异常处理机制的栈框架大概是什么样子
:
剩余12页未读,继续阅读
资源评论
- lejiang01102014-05-09详细,赞,谢谢分享
- jiandan03222012-10-21详细且具体~
enic
- 粉丝: 52
- 资源: 169
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功