Я пытаюсь выучить C, написав простой парсер / компилятор.До сих пор это был очень поучительный опыт, однако из-за сильного опыта в C # у меня возникли некоторые проблемы с адаптацией - в частности, из-за отсутствия исключений.
Теперь я прочитал Очиститель, большеэлегантный, и труднее узнать , и я согласен с каждым словом в этой статье;В моем коде на C # я по возможности не выкидываю исключения, однако теперь, когда я столкнулся с миром, в котором не могу выбрасывать исключения, моя обработка ошибок полностью затопляет понятную и простую для чтения логикумоего кода.
В данный момент я пишу код, который должен быстро сбоить , если есть проблема, и она также потенциально глубоко вложена - я остановился на обработке ошибокшаблон, посредством которого функции «Get» возвращают NULL при ошибке, а другие функции возвращают -1
при ошибке.В обоих случаях вызывающая сбой функция вызывает NS_SetError()
, поэтому все, что нужно сделать вызывающей функции, - это очистить и немедленно вернуться к ошибке.
Моя проблема в том, что число операторов if (Action() < 0) return -1;
, которые яЯ имею дело с головой - это очень повторяется и полностью затемняет основную логику.Я закончил тем, что создал себе простой макрос, чтобы попытаться улучшить ситуацию, например:
#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
в случае ошибки - это лучше , но все равно кажется, что я злоупотребляю макросами и не допускаю очистки (некоторые функции, в частности функции Get
, которые возвращаютуказатель, он более сложный и требует запуска кода очистки).
В целом кажется, что я что-то упустил - несмотря на то, что обработку ошибок таким способом предположительно легче распознать,Многие из моих функций я действительно пытаюсь определить, правильно ли обрабатываются ошибки:
- Некоторые функции возвращают
NULL
при ошибке - Некоторые функции возвращают
< 0
об ошибке - Некоторые функции никогда не выдают ошибку
- Мои функции делают
NS_SetError()
, но многие другие функции этого не делают.
Есть ли лучшетак, что я могу структурировать свой функционалили у всех остальных тоже есть эта проблема?
Имеет также Get
функции (которые возвращают указатель на объект), возвращающие NULL
в случае ошибки, хорошая идея, или это просто сбивает с толку моюобработка ошибок?