// names are unique within a function, any valid variable name
// a jump table try, allowing return values to determine the exception thrown(index in a jump table, -1 being success for example)
// you only need to put in what you need, not all exceptions, or total exception count
#define GTRY(name, exc) void* __jt_##name[exc];int __jtix_##name = 0;
// register an exception in the jump table. you don't need to do them all
#define GTEX(name, exception) __jtix_##name;__jt_##name[__jtix_##name++] = &&__tr_##exception##name;
// resets the jump table index to a given value, useful for overwriting exceptions without a new try.
#define GTRST(name, index) __jtix_##name = index;
// a standard try, doesn't actually add anything, but for cleanliness.
#define TRY(name) ;
// throw an exception by name
#define THROW(name, exception) goto __tr_##exception##name;
// throws an exception by jump table index
#define GTHROW(name, exn) goto *__jt_##name[exn];
// begins a catch block
#define CATCH(name, exception) goto __trend_##name;__tr_##exception##name:;
// signifies where the try ends
#define ENDTRY(name) __trend_##name:;
// 'finally' blocks need only be put after an end try.用法示例:
int main(int argc, char* argv[]) {
TRY(magic)
THROW(magic, EOF)
CATCH(magic, EOF)
printf("eof!\n");
ENDTRY(magic)
printf("complete\n");
GTRY(fagic, 2)
int eof = GTEX(fagic, EOF)
int rst = GTEX(fagic, RST)
GTHROW(fagic, rst)
CATCH(fagic, EOF)
printf("eof2!\n");
CATCH(fagic, RST)
printf("rst\n");
ENDTRY(fagic);
//
TRY(nest) {
THROW(nest, EOF);
} CATCH(nest, EOF) {
printf("eof3!\n");
}
ENDTRY(nest)
printf("complete3\n");
return 0;
}我的目的是创建一个基于宏的异常系统,它可以轻松地在嵌入式设备上运行(魔术是编译时完成的)。如果CPU不支持作为值的标签,并且使用GTRY,则会有潜在的性能问题。
发布于 2016-07-06 15:31:14
语义学
在实现try、throw和catch的语言中,范围通常大于单个函数。异常处理的范围由try块和catch块设置。C goto仅限于当前函数,要跳出当前函数,需要使用setjmp()和longjmp()。您的实现似乎不使用setjmp()和longjmp()。
维修性
使用goto通常会降低可维护性,隐藏goto是个坏主意。如果我必须维护包含goto的代码,我希望能够立即知道有一个goto,并且我希望能够立即找到标签。
性能
使用goto的一个原因是改善性能。当goto实际上降低性能时,这也是不使用它们的另一个原因。
https://codereview.stackexchange.com/questions/134022
复制相似问题