c – 使用volatile安全使用longjmp / setjmp

我考虑使用基于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”而臭名昭着.

点赞