我考虑使用基于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;
}
事实上是宏观
#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是易变的,而前一个声明会使指针易变?
答案 0 :(得分:2)
u32 *volatile var
使指针变为易失性,而volatile u32 *var
告诉编译器该地址的数据是易失性的。因此,由于在后一个示例中指针不是易失性的,所以如果您的编译器将default
情况完全优化为result = NULL;
之类的话,我不会感到惊讶。
它可能不会指望setjmp
魔法,而这些甚至比“goto
更多的意大利面条而臭名昭着。”