C语言 安全使用longjmp/setjmp与volatile



我考虑使用基于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更意大利面"。

最新更新