我考虑使用基于setjmp/longjmp的TRY/CATCH宏来处理错误。否则,我的一些相当结构化的函数将被丑陋的if语句和循环标志搞得一团糟。
代码如下:
int trycatchtest(int i)
{
int result = 0;
volatile int error = 100;
volatile uint32_t *var = NULL;
TRY
{
error = 0;
var = os_malloc(4);
*var = 11;
if (i) THROW( i );
}
FINALLY
{
result = *var;
}
END;
return result;
}
THROW实际上是宏
#define TRY do { jmp_buf buf; switch( setjmp(buf) ) { case 0: while(1) {
#define FINALLY break; } default: {
#define END break; } } } while(0)
#define THROW(x) longjmp(buf, x)
问题:
当抛出异常时(例如i=1),指针var被重置为NULL,尽管我使用了volatile关键字,这应该避免使用寄存器。从调试器中,我看到它仍然在寄存器中,而不是在内存中。
我写错了吗?
编辑:我把var的声明改成了
uint32_t * volatile var = NULL;
可以;-)
我真的不明白有什么区别:
volatile uint32_t * var = NULL;
意味着VALUE是易失性的,而前一个声明使指针易失性?
u32 *volatile var
使指针易失性,而volatile u32 *var
告诉编译器该地址的数据是易失性的。因此,由于指针在后一个例子中不是易失性的,如果您的编译器将default
情况完全优化为result = NULL;
之类的情况,我不会感到惊讶。
它可能不期望setjmp
的魔法,这些是臭名昭著的"比goto
更意大利面"。