exceptions4c库(e4c)
https://github.com/guillermocalvo/exceptions4c
image image1.介绍
通过这个小巧的可移植库,为您的C应用程序带来异常的强大功能。
2、C的异常处理框架
这个库为您提供了一组简单的关键字(实际上是宏),它们映射了您可能已经习惯的异常处理语义:
- try
- catch
- finally
- throw
你可以用异常在C写try/catch/finally块:
#include "e4c.h"
int foobar(){
int foo;
void * buffer = malloc(1024);
if(buffer == NULL){
throw(NotEnoughMemoryException, "Could not allocate buffer.");
}
try{
foo = get_user_input(buffer, 1024);
}catch(BadUserInputException){
foo = 123;
}finally{
free(buffer);
}
return(foo);
}
这样,您就再也不必处理无聊的错误代码,或者在每次调用函数时检查返回值。
3.异常层次结构
程序中可能的异常组织在异常的伪层次结构中。RuntimeException是异常伪层次结构的根。任何异常都可以被catch(RuntimeException)块捕获,AssertionException(断言异常)除外。
当抛出异常时,控制被转移到最近的动态封闭catch代码块,该代码块处理异常。通过比较实际抛出异常的类型(和超类型)与catch子句中指定的异常,可以确定特定catch块是否处理异常。
catch块作为参数给出一个异常。此参数确定可由代码块处理的异常集。一个块处理一个实际的异常,如果指定的参数是:
- 相同类型的异常。
- 该异常的任何超类型的相同类型。
如果您编写一个catch块来处理没有定义子类型的异常,那么它将只处理非常特定的异常。通过在层次结构中对异常进行分组,您可以设计处理多个异常的通用catch块:
/* Name Default message Supertype */
E4C_DEFINE_EXCEPTION(ColorException, "Colorful error.", RuntimeException);
E4C_DEFINE_EXCEPTION(RedException, "Red error.", ColorException);
E4C_DEFINE_EXCEPTION(GreenException, "Green error.", ColorException);
E4C_DEFINE_EXCEPTION(BlueException, "Blue error.", ColorException);
...
try{
int color = chooseColor();
if(color == 0xff0000) throw(RedException, "I don't like it.");
if(color == 0x00ff00) throw(GreenException, NULL);
if(color == 0x0000ff) throw(BlueException, "It's way too blue.");
doSomething(color);
}catch(GreenException){
printf("You cannot use green.");
}catch(ColorException){
const e4c_exception * e = e4c_get_exception();
printf("You cannot use that color: %s (%s).", e->name, e->message);
}
在寻找匹配项时,将按照catch块在代码中出现的顺序检查它们。如果将超类的处理程序放在子类处理程序之前,则第二个块实际上是不可访问的。
4.处理模式
还有其他关键词与资源处理相关
- with...use
- using
它们允许您在代码中表达Dispose模式:
/* syntax #1 */
FOO f;
with(f, e4c_dispose_FOO) f = e4c_acquire_FOO(foo, bar); use do_something(f);
/* syntax #2 (relies on 'e4c_acquire_BAR' and 'e4c_dispose_BAR') */
BAR bar;
using(BAR, bar, ("BAR", 123) ){
do_something_else(bar);
}
/* syntax #3 (customized to specific resource types) */
FILE * report;
e4c_using_file(report, "log.txt", "a"){
fputs("hello, world!\n", report);
}
这是一种简洁明了的处理各种资源的方法,具有隐式获取和自动处理功能。
5.信号处理
此外,SIGHUP、SIGFPE和SIGSEGV等信号可以以一种特殊的方式处理。忘掉可怕的分割错误吧,你只需要捕捉BadPointerException:
int * pointer = NULL;
try{
int oops = *pointer;
}catch(BadPointerException){
printf("No problem ;-)");
}
6.多线程
如果在程序中使用线程,则必须通过在编译器级别定义E4C_THREADSAFE来启用库的线程安全版本。
框架的使用在单线程和多线程程序之间没有区别。同样的语义也适用。唯一需要注意的是,信号处理的行为在多线程程序中是未定义的,因此请谨慎使用此特性。
7.集成
无论您是开发独立的应用程序,还是为独立程序提供服务的外部库,都可以非常容易地在代码中集成exceptions4c。
系统为异常框架的隐式初始化和最终化提供了一种机制,这样就可以安全地使用来自任何外部函数的try、catch、throw等,即使调用者没有任何异常感知。
8.可移植性
这个库可以在任何ANSIC编译器中编译。它只使用标准的C函数。为了使用exceptions4c,您必须删除项目中的两个文件(e4c.h和e4c.c),并记住从代码中包含头文件。
如果您的应用程序使用线程,exceptions4c依赖于pthreads (POSIX应用程序编程接口,用于编写多线程应用程序)。这个API适用于大多数操作系统和平台。
9.轻量级版本
如果您觉得exceptions4c的标准版本对于您的特定需求可能有些过分,那么有一个轻量级版本,它针对小型项目和嵌入式系统。当您只想通过简单而强大的异常处理机制处理程序中可能发生的错误条件时,可以使用它。它在不到200行代码中提供了exceptions4c的核心功能。
网友评论