使用volatile安全使用longjmp / setjmp

时间:2016-09-12 07:49:52

标签: c exception-handling longjmp

我考虑使用基于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是易变的,而前一个声明会使指针易变?

1 个答案:

答案 0 :(得分:2)

u32 *volatile var使指针变为易失性,而volatile u32 *var告诉编译器该地址的数据是易失性的。因此,由于在后一个示例中指针不是易失性的,所以如果您的编译器将default情况完全优化为result = NULL;之类的话,我不会感到惊讶。

它可能不会指望setjmp魔法,而这些甚至比“goto更多的意大利面条而臭名昭着。”