C++ exception 的问题

今天在 C++ 会议上认识的鲍同学发了封 email 过来,顺着他的 email 我找到了<a href="http://spaces.msn.com/members/wesleybao/">他的 blog</a>。发现最上面谈的是关于 C++ 异常的问题。
<a href="http://spaces.msn.com/members/wesleybao/Blog/cns!1p0i3yoUKRgnWt0UyAV1FMog!935.entry">Exception handling in depth</a>

的确在大会的第2天我去听了这个演讲,老实说,其内容我觉得不符合我的预期,所以半途我跑到隔壁去听荣耀讲模板元编程了。

当时讲师前半段一直在讲 SEH ,和 C++ 关系不大。我本以为会讲 C++ 异常的实现的,我个人以前研究过一些,很有兴趣听听人家的理解,结果没有听到。据说后来那个会场最终吵了起来,很遗憾没有领略那个盛况 :)

鲍同学提到 VC6 的实现问题,我可以证明,VC6 的异常处理,在 happy path 上是没有什么内核 API 调用的。
VC6 的异常处理也不比 icc gcc 什么的差。是不是好点我就说不准了。

unhappy path 的性能我个人不是很关心。我想大家也不会太关心吧。

不过,VC6 上关掉异常是可以提高性能的。因为毕竟有些环境需要设置,VC6 会利用 fs 保存一些环境信息。而且无论是什么编译器实现,因为需要处理 unhappy path 一般需要编译自动生成大量的代码。这比你只用返回值一定会生成更多更长的字节数。只是因为大家现在都不大关心代码体积,这个问题被掩盖了。我个人在某些情况下是在乎这个的。而且代码体积增加也意味着略微的时间效率损失,ICC 或许会优化的好一些,让其在 happy path 上,对性能影响最小,比如调远 unhappy path 的 code 的物理距离等。

除零的问题是这样,一般非数学计算的程序,我们很少用除法,即使用到,大多数情况,程序逻辑可以保证其不为0。而数学计算的程序一般又用的浮点数,除零得到的是无穷大并不抛出异常。所以我并不认为用除0异常来体现异常的优越性有特别大的说服力。

我个人因为特定的项目环境的原因,是不使用异常机制的。大部分情况下,处理 unhappy path 用 goto 足亦。这里就扯到 goto 的问题。goto 在很多人看来很不耻。不过我认为在函数设置一些出口点,然后 goto 是一种很优美的方法。

其实不用异常的好处也很多,首先程序的复杂性降低了,否则程序的流程会比较复杂,对程序员的要求更高。其次,接口的设计也会比较简单,最后性能会有那么一点的提高。而且,我的程序曾经大量使用 coroutine,C++ 异常对此很难支持。呵呵,言多必失,我对异常几乎没怎么用,都是理论知识,不敢多评论了。

其实偶还是支持鲍同学大部分观点的 :)

评论