Я рассматриваю использование макроса TRY/CATCH на основе setjmp/longjmp для обработки ошибок. В противном случае некоторые из моих вполне структурированных функций будут взорваны уродливыми операторами if и флагами цикла.Безопасное использование longjmp/setjmp с volatile
Код как в этом примере:
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)
Проблема:
Когда исключение (например, я = 1) указатель var сбрасывается в NULL, хотя я использовал ключевое слово volatile, которое должно избегать использования для него регистра. Из отладчика я вижу, что это все еще в регистре, а не в памяти.
Я допустил ошибку?
EDIT:
Я изменил декларацию вар в
uint32_t * volatile var = NULL;
Это работает ;-)
Я не очень понимаю, в чем разница:
volatile uint32_t * var = NULL;
средства , что VALUE нестабильна, тогда как прежняя декларация делает указатель изменчивым?
Когда я компилирую этот код и 'printf ("% d \ n ", trycatchtest (1));' он возвращает '11' ... Как вы скомпилировали и какие флаги вы использовали? – tversteeg
Я согласен с @tversteeg, он работает и на моей машине. Какой компилятор/платформа это? Как определяется 'os_malloc', предположительно, вы делаете какие-то вложенные/RTOS-материалы? – Groo
см. Мое редактирование выше! – michael