五、错误处理:
1、错误报告处理。
编程中要求考虑函数的各种执行情况,尽可能处理所有的流程情况。将函数分为两类:
一类为与屏幕的显示无关,(不与用户交换信息的函数)
一类为与屏幕的显示相关。(与用户交换信息的函数)
对于与屏幕显示无关的函数,函数通过返回值来报告错误。
对于与屏幕显示有关的函数,函数要负责向用户发出警告,并进行错误处理。
错误处理代码一般单独建立通用处理函数。如下:
void cmDeal_With_Error(long ErrCode)
{
switch(ErrCode)
{
case 1://注释
......
case 2://注释
......
default://注释
......
}
}
2、尽早发现程序中的错误:
①、重视编译器中的警告信息。
对于编译器产生的警告信息,我们应该引起足够的重视,实际上许多警告信息指示了程序中潜在的错误危险。所以我们要认真检查每一个警告信息,查看是否有某种隐患。尽量消除警告信息。
②、利用断言来检查错误
对于程序中的某种假设,或防止某些参数的非法值,利用断言来帮助查错是一种好的办法。
例如下面的函数:
long cmMemCpy(void * pvToMem, void* pvFromMem, size_t wSize)
{
……
if(pvToMem==NULL||pvFromMem==NULL)
{
lResult=CM _POINT_IS_NULL;
goto: END;
}
while(wSize-- >0)
{
*pvToMem++=pvFromMem++;
}
END:
return lResult;
}
采用判断可以检查传入的指针错误,但是这样的判断是程序最终的编译代码变大,同时降低了最终发布的程序的执行效率。由于传入空指针明显是调用这函数的程序的错误,而不是这个函数的错误,我们可以考虑采用断言来代替指针检查,即用
ASSERT( pvToMem!=NULL&&pvFromMem!=NULL)
代替
if(pvToMem==NULL||pvFromMem==NULL)
{
lResult=CM_POINT_IS_NULL;
goto: END;
}
这样只会在debug版中才会产生检查代码,而在正式发布版中不会带有这些代码。并且可以方便我们在程序调试中和测试时发现错误,同时又不影响程序的效率。
在下面的一些情况中必须加断言:
a、数的参数,特别是指针参数必须利用断言来进行确认。
b、利用断言检查程序中的各种假设的正确性。
c、在程序设计中不要轻易认为某种情况不可能发生,对你认为不可能发生的情况必须用断言来证实。
为了使程序中的断言发挥作用,所有用于在开发内部进行测试或调试的动态库、执行程序、组件必须采用debug版。
说明:
在程序效率要求较高、或者调用比较频繁的函数,对入口参数的错误检查,使用断言方式,其优点如上所叙,但其健壮性不强,所以在其他情况下,仍要求使用传统的检查方式,以增强程序的健壮性,当然,为了调试方便,可同时使用断言方式。
③、严格的测试:
对每一段代码都要求进行严格的测试,特别对一些功能函数要对其各种临界点(比如零值、无穷大的值等)进行测试。尽量做到每一段代码零错误。