Reputation: 1464
I consider to use a TRY/CATCH macro based on setjmp/longjmp for error handling. Otherwise some of my quite structued functions will be blown up by ugly if statements and loop flags.
The code is like this example:
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 is in fact the macro
#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)
The Problem:
When the exception is thrown (e.g. i=1) the pointer var is reset to NULL, although I used the volatile keyword, which should avoid using a register for it. From the debugger I see that is is still within a register and not in memory.
Did I make a mistake ?
EDIT:
I changed declaration of var into
uint32_t * volatile var = NULL;
This works ;-)
I do not really understand what is the difference:
volatile uint32_t * var = NULL;
means, that the VALUE is volatile, whereas the former declararation makes the pointer volatile?
Upvotes: 3
Views: 635
Reputation: 51224
u32 *volatile var
makes the pointer volatile, while volatile u32 *var
tells the compiler that the data at that address is volatile. So since the pointer is not volatile in the latter example, I wouldn't be surprised if your compiler optimized away the default
case completely to something like result = NULL;
.
It probably doesn't expect the setjmp
wizardry, and these are notorious for being even "more spaghetti than goto
".
Upvotes: 3