Как обрабатывать ошибки - PullRequest
       1

Как обрабатывать ошибки

0 голосов
/ 06 февраля 2012

Мне было интересно, как лучше всего обрабатывать ошибки в программировании (я пишу на C). Я новичок в программировании, и это то, что я делаю:

if( action1 was successfull )
{
   [some code]
   if (action 2 was successfull)
   {
      [some more code ..]
      if (action 3 was successfull)
      {
         ETC ... 
      }
      else
      {
        [Handle error3]
      }
   }
   else
   {
     [handle error2]
   }
}
else
{
  [Handle error1]
}

Но я думаю, что это дурной привычка ... Может кто-нибудь объяснить мне, какой самый элегантный способ сделать это? Спасибо

Ответы [ 3 ]

4 голосов
/ 06 февраля 2012

Иногда код, который вы показываете, действительно является наилучшим доступным вариантом, но вот некоторые альтернативы.

Часто вместо этого вы можете структурировать свой код следующим образом:

if (action_1() failed) {
    report error;
    return -1;
}
if (action_2() failed) {
    report error;
    return -1;
}
/* etc */

Эта конструкция объясняет, почемуЭто обычная идиома C для возврата 0 в случае успеха или -1 в случае неудачи: она позволяет записать if (action_1() failed) как просто if (action_1()).

Если вам нужно выполнить некоторую очистку перед возвратом и очисткудействия аккуратны, это еще одна возможность:

if (action_1()) {
    report error;
    goto fail_a1;
}
if (action_2()) {
    report error;
    goto fail_a2;
}
if (action_3()) {
    report error;
    goto fail_a3;
}
/* etc */
return 0;

/* errors */
/* etc */
fail_a3:
  clean up from a2;
fail_a2:
  clean up from a1;
fail_a1:
  return -1;

Настоящим вам разрешается использовать goto для этого.

4 голосов
/ 06 февраля 2012

Я делаю это так:

// more code
if (!action_1_succeeded())
{
   handle_error();
   return;
}

// more code
if (!action_2_succeeded())
{
   handle_error();
   return;
}

// more code
if (!action_3_succeeded())
{
   handle_error();
   return;
}

Обычно я обертываю handle_error и return в макрос, поэтому я просто делаю check_error(some_statement());

1 голос
/ 06 февраля 2012

Вы можете создавать идентификаторы ошибок и связывать обработчик ошибок с определенным типом ошибок.

typedef struct _error {
  void (*handler)(struct _error *); 
  int i_params;
  char *c_params;
} error;

void nope(error * e) {}
void file_err(error * e) { exit(1); }

error handlers[200];

void check_error(int id) {
  handlers[id].handler(&handlers[id]);
}

enum error { ER_SUCCESS, ER_FILE};
int main() {
  handlers[ER_SUCCESS].handler = nope;
  handlers[ER_FILE].handler = file_err;
  check_error(action1());
  return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...