VisualC 中的异常处理浅析
2008-04-09 04:10:01来源:互联网 阅读 ()
Visual C 提供了对C语言、C 语言及MFC的支持,因而其涉及到的异常(exception)处理也包含了这三种类型,即C语言、C 语言和MFC的异常处理。除此之外,微软对C和C 的异常处理进行了扩展,提出了结构化异常处理(SEH)的概念,它支持C和C (与之相比,MFC异常处理仅支持C )。
一个典型的异常处理包含如下几个步骤:
(1)程序执行时发生错误;
(2)以一个异常对象(最简单的是一个整数)记录错误的原因及相关信息;
(3)程序检测到这个错误(读取异常对象);
(4)程序决定如何处理错误;
(5)进行错误处理,并在此后恢复/终止程序的执行。
C、C 、MFC及SEH在这几个步骤中表现出了不同的特点。本文将对这四种异常处理进行介绍,并对它们进行对比分析。本文例程的调试平台为Visual C 6.0,操作系统为Windows XP,所有程序均调试通过。
1.C语言异常处理
1.1 异常终止
标准C库提供了abort()和exit()两个函数,它们可以强行终止程序的运行,其声明处于<stdlib.h>头文件中。这两个函数本身不能检测异常,但在C程序发生异常后经常使用这两个函数进行程序终止。下面的这个例子描述了exit()的行为:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
exit(EXIT_SUCCESS);
printf("程序不会执行到这里\n");
return 0;
}
在这个例子中,main函数一开始就执行了exit函数(此函数原型为void exit(int)),因此,程序不会输出"程序不会执行到这里"。程序中的exit(EXIT_SUCCESS)表示程序正常结束,与之对应的exit(EXIT_FAILURE)表示程序执行错误,只能强行终止。EXIT_SUCCESS、EXIT_FAILURE分别定义为0和1。
对于exit函数,我们可以利用atexit函数为exit事件"挂接"另外的函数,这种"挂接"有点类似Windows编程中的"钩子"(Hook)。譬如:
#include <stdio.h>
#include <stdlib.h>
static void atExitFunc(void)
{
printf("atexit挂接的函数\n");
}
int main(void)
{
atexit(atExitFunc);
exit(EXIT_SUCCESS);
printf("程序不会执行到这里\n");
return 0;
}
程序输出"atexit挂接的函数"后即终止。来看下面的程序,我们不调用exit函数,看看atexit挂接的函数会否执行:
#include <stdio.h>
#include <stdlib.h>
static void atExitFunc(void)
{
printf("atexit挂接的函数\n");
}
int main(void)
{
atexit(atExitFunc);
//exit(EXIT_SUCCESS);
printf("不调用exit函数\n");
return 0;
}
程序输出:
不调用exit函数
atexit挂接的函数
这说明,即便是我们不调用exit函数,当程序本身退出时,atexit挂接的函数仍然会被执行。
atexit可以被多次执行,并挂接多个函数,这些函数的执行顺序为后挂接的先执行,例如:
#include <stdio.h>
#include <stdlib.h>
static void atExitFunc1(void)
{
printf("atexit挂接的函数1\n");
}
static void atExitFunc2(void)
{
printf("atexit挂接的函数2\n");
}
static void atExitFunc3(void)
{
printf("atexit挂接的函数3\n");
}
int main(void)
{
atexit(atExitFunc1);
atexit(atExitFunc2);
atexit(atExitFunc3);
return 0;
}
输出的结果是:
atexit挂接的函数3
atexit挂接的函数2
atexit挂接的函数1
在Visual C 中,如果以abort函数(此函数不带参数,原型为void abort(void))终止程序,则会在debug模式运行时弹出如图1所示的对话框。
图1 以abort函数终止程序
1.2 断言(assert)
assert宏在C语言程序的调试中发挥着重要的作用,它用于检测不会发生的情况,表明一旦发生了这样的情况,程序就实际上执行错误了,例如strcpy函数:
char *strcpy(char *strDest, const char *strSrc)
{
char *address = strDest;
assert((strDest != NULL) && (strSrc != NULL));
while ((*strDest = *strSrc ) != ’\0’)
;
return address;
}
其中包含断言assert( (strDest != NULL) && (strSrc != NULL) ),它的意思是源和目的字符串的地址都不能为空,一旦为空,程序实际上就执行错误了,会引发一个abort。
assert宏的定义为:
#ifdef NDEBUG
#define assert(exp) ((void)0)
#else
#ifdef __cplusplus
extern "C"
{
#endif
_CRTIMP void __cdecl _assert(void *, void *, unsigned);
#ifdef __cplusplus
}
#endif
#define assert(exp) (void)( (exp) || (_assert(#exp, __FILE__, __LINE__), 0) )
#endif /* NDEBUG */
如果程序不在debug模式下,assert宏实际上什么都不做;而在debug模式下,实际上是对_assert()函数的调用,此函数将输出发生错误的文件名、代码行、条件表达式。例如下列程序:
#include <stdio.h>
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash