【发布时间】:2016-09-12 07:49:52
【问题描述】:
我考虑使用基于 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是volatile的,而前面的声明使得指针是volatile的?
【问题讨论】:
-
当我编译这段代码和
printf("%d\n", trycatchtest(1));它返回11...你是如何编译的,你使用了什么标志? -
我同意@tversteeg,它也适用于我的机器。这是哪个编译器/平台?
os_malloc是如何定义的,大概你在做一些嵌入式/RTOS 的东西? -
在上面查看我的编辑!
-
这是一些非常丑陋和危险的代码。不要这样写废话,它比“on error goto”模式要糟糕得多。这又比“函数返回错误代码”更糟糕。
-
我同意@Lundin,“on error goto”模式(例如,在 Linux 内核源代码中广泛使用)比这种废话更可取。您的
trycatchtest函数似乎存在内存泄漏,尽管您仅使用它来测试您的宏。由于buf是一个局部变量,这些宏在嵌套的函数调用中不起作用,那么为什么需要为这些宏使用setjmp/longjmp呢?
标签: c exception-handling setjmp