参考文章:
这篇文章介绍了基本的错误处理概念:http://www.learncpp.com/cpp-tutorial/712-handling-errors-assert-cerr-exit-and-exceptions/
异常的处理:http://mindhacks.cn/2012/08/27/modern-cpp-practices/
http://www.cnblogs.com/mavaL/articles/2515381.html
程序崩溃的处理方式:http://blog.youkuaiyun.com/starlee/article/category/268202
异常处理知乎上的争论:http://www.zhihu.com/question/22889420/answer/22979344
1.错误的分类
(1)语法错误
这个是显而易见的,语法错误一般逃不过编译器的双眼。
(2)语义错误
可以把这个定义为,程序语法上有效但是由于各种疏漏并没有实现程序员预想的目标。
注:这篇文章关注的是语义错误。
2.语义错误的分类
(1)可以预料到的情况
比如,①分配一块内存失败。②进行socket的读取失败。③打开一个文件失败。④得到无效的用户的输入。
这些一般都是在预料中的可能出现的情况,并且很容易就知道如何处理。
(2)没有预料到的漏洞
比如,①在不知道的情况下用0作为除数。②在不知道的情况下越界。
注:其实这里对于(1)(2)的区分不够明白,下面更详细地说明一下。
(1)(2)最主要的区别就是,(1)应该是可以预先预料到的一些错误,并且这些错误就算你能够预知也不能阻止其发生,但是你知道如何去处理。
处理的意思就是释放该释放的资源,恢复程序的正常运行等。
(2)应该包括所有自己没有预料到的情况,当你察觉到以后:①它就变成了(1)中的错误。②你直接能改正,这种便错误不会发生。③你还在寻找解决办法。
3.错误的处理方式
(1)直接处理
对于那些很容易预料到,进行if判断后,直接就处理了。
对于比较小型的程序,比如读取用户输入的字母转换为大写。
如果用户输入了数字,我们可以判断后,提示用户使用户重新输入。
(2)异常
使用异常,在C++中就是承诺了这样一种机制,
如果某种错误发生,我会对我预料到的情况进行处理,处理后程序继续执行。但是如果不进行处理,即使这个错误本身不会崩溃程序,随着这个异常的传递,程序也会崩溃。
所以轮子哥主张:异常能处理的catch处理,比如socket读取失败。不能处理的,就让它崩溃,做好dump,然后调试程序为正确的,比如vector越界了。
所以使用异常和异常是用来catch的是两个不同的概念。
注:(2)和(1)的比较,有些错误不是直接用个if判断就能看到的,中间可能涉及到参数传递,函数调用,这个时候借助异常就更方便一些。
也提供了一种规范统一的方法来进行处理。
(3)断言
在程序执行前,进行某条件的判断。如果判断失效,程序继续执行。
如果判断有效,打印一些文件信息,然后程序结束。
(4)就让程序结束吧
不管你是想dump后体面地退出,还是直接就让它崩了。
崩了之后也还有不同处理方式:
①如果有callstack工具,可以callstack调试。
②如果有dump工具,可以dump出来查看各种进程运行的信息。