Я думаю использовать макрос TRY/CATCH на основе setjmp/longjmp для обработки ошибок. В противном случае некоторые из моих хорошо структурированных функций будут разрушены уродливыми операторами 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;
означает, что ЗНАЧЕНИЕ является изменчивым, тогда как предыдущее объявление делает указатель изменчивым?
printf("%d\n", trycatchtest(1));
он возвращает11
... Как вы компилировали и какие флаги использовали? - person tversteeg   schedule 12.09.2016os_malloc
, предположительно, вы делаете какие-то встроенные/RTOS вещи? - person Groo   schedule 12.09.2016trycatchtest
имеет утечку памяти, хотя вы используете ее только для проверки своих макросов. Посколькуbuf
является локальной переменной, эти макросы не будут работать при вызовах вложенных функций, так зачем вам нужно использоватьsetjmp
/longjmp
для этих макросов? - person Ian Abbott   schedule 12.09.2016setjmp
/longjmp
для этих макросов, а неgoto
и локальная метка, и это связано с метками, имеющими область действия, а не область действия блока. Я бы все равно не использовал эти макросы! - person Ian Abbott   schedule 12.09.2016