Есть ли лучший способ обработки ошибок в стиле C?

Я пытаюсь изучить C, написав простой парсер / компилятор. До сих пор это был очень поучительный опыт, однако, исходя из сильного опыта в C #, у меня возникли некоторые проблемы с настройкой - в частности, из-за отсутствия исключений.

Теперь я ' Мы читали Чище, элегантнее и труднее узнавать , и я согласен с каждым словом в этой статье; В моем коде на C # я стараюсь по возможности не генерировать исключения, однако теперь, когда я столкнулся с миром, в котором я не могу генерировать исключения, моя обработка ошибок полностью затмевает чистую и легкую для чтения логику. моего кода.

В настоящий момент я пишу код, который должен быстро выходить из строя , если есть проблема, а также потенциально глубоко вложен - я остановился на шаблоне обработки ошибок, согласно которому " Функции Get возвращают NULL в случае ошибки, а другие функции возвращают -1 в случае ошибки. В обоих случаях функция, которая терпит неудачу, вызывает NS_SetError () , поэтому все, что нужно сделать вызывающей функции, - это очистить и немедленно вернуться в случае ошибки.

Моя проблема в том, что количество if (Action () операторов, которые у меня есть, мешает мне - это очень повторяющееся и полностью скрывает основную логику. В итоге я создал себе простой макрос, чтобы попытаться улучшить ситуацию, например:

#define NOT_ERROR(X)    if ((X) < 0) return -1

int NS_Expression(void)
{
    NOT_ERROR(NS_Term());
    NOT_ERROR(Emit("MOVE D0, D1\n"));

    if (strcmp(current->str, "+") == 0)
    {
        NOT_ERROR(NS_Add());
    }
    else if (strcmp(current->str, "-") == 0)
    {
        NOT_ERROR(NS_Subtract());
    }
    else
    {
        NS_SetError("Expected: operator");
        return -1;
    }
    return 0;
}

Каждая из функций NS_Term , NS_Add и NS_Subtract выполните NS_SetError () и верните -1 в случае ошибки - его лучше , но все равно кажется, что я злоупотребляю макросами и не t допускают любую очистку (некоторые функции, в частности функции Get , которые возвращают указатель, более сложны и требуют запуска кода очистки).

В целом это похоже на то, что я ' > ...

Документация, с которой я столкнулся, исследуя это, указывает на то, что способ сделать это для других баз данных - это использовать несколько операторов в вашем запросе, а-ля:

>>> cursor = connection.cursor()
>>> cursor.execute("set session transaction isolation level read uncommitted; 
                    select stuff from table; 
                    set session transaction isolation level repeatable read;")

К сожалению, это не дает результатов, поскольку очевидно, Python DB API (или, может быть, его реализация?) не поддерживает несколько наборов записей в одном запросе.

Кто-нибудь еще добился успеха с этим в прошлом?

9
задан jodonnell 15 April 2011 в 13:17
поделиться