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