我考虑使用基于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是易变的,而前面的声明使指针易变。
printf("%d\n", trycatchtest(1));
输出时,它返回了11
... 你是怎么编译的,用了什么标志? - tversteegos_malloc
是如何定义的,可能你正在做一些嵌入式/RTOS相关的工作? - vgrutrycatchtest
函数似乎存在内存泄漏问题,尽管你只是用它来测试你的宏。由于buf
是一个局部变量,这些宏在嵌套函数调用中不起作用,那么为什么你需要使用setjmp
/longjmp
来实现这些宏呢? - Ian Abbottsetjmp
/longjmp
来实现这些宏,而不是使用goto
和本地标签,这是因为标签具有函数作用域,而不是块作用域。但我仍然不会使用这些宏! - Ian Abbott