1-1 传统的错误处理

1.1 传统的错误处理

本书说明

  1. debug模式下,使用assert来进行开发时调试,在发布时通过#define NDEBUG来使其失效。

  2. 运行时错误处理采用require.h中定义的assurerequire函数。

1. C语言中的错误处理方式

  • 函数中返回错误信息

    • 问题:错误检查冗长乏味
  • 鲜为人知的C库信号处理系统,即signal函数和raise函数

    • 问题:项目中代码耦合度过高,不同库的信号值可能会发生冲突
  • C库的非局部跳转函数:setjmp和longjmp

    • 问题:在C++中跳出作用域时,不会调用析构函数,非常危险。
一个setjmp和longjmp的演示程序

本程序演示了setjmp和longjmp的运作流程:先调用一次setjmp,再使用oz函数创建一个对象,其中使用longjmp跳回setjmp的if判断,并证明了对象不被析构(goto也是如此)。接着返回值变为47,进入else。

#include <iostream>
#include <csetjmp>
using namespace std;

class Rainbow
{
public:
Rainbow() { cout << "Rainbow()" << endl; }
~Rainbow() { cout << "~Rainbow()" << endl; }
};

jmp_buf kansas;

void oz()
{
Rainbow rb;
for (int i = 0; i < 3; i++)
cout << "There is no place like home" << endl;
longjmp(kansas, 47);
}

int main()
{
if (setjmp(kansas) == 0)
{
cout << "tornado, switch, munchins..." << endl;
oz();
}
else
{
cout << "Auntie Em!"
<< "I had the strangest dream..."
<< endl;
}
return 0;
}
/*output:
tornado, switch, munchins...
Rainbow()
There is no place like home
There is no place like home
There is no place like home
Auntie Em!I had the strangest dream...
*/