хороший стиль c при проверке большого количества возвращаемых значений - PullRequest
11 голосов
/ 09 марта 2010

Иногда мне приходится писать код, который чередуется между выполнением действий и проверкой на наличие ошибок (например, вызов функции библиотеки, проверка ее возвращаемого значения, продолжение работы). Это часто приводит к длительным периодам, когда фактическая работа происходит в условиях операторов if, таких как

if(! (data = (big_struct *) malloc(sizeof(*data)))){
    //report allocation error
} else if(init_big_struct(data)){
    //handle initialization error
} else ...

Как вы, ребята, пишете такой код? Я проверил несколько руководств по стилю, но они, похоже, больше связаны с именами переменных и пробелами.

Ссылки на руководства по стилю приветствуются.

Редактировать: если неясно, я недоволен разборчивостью этого стиля и ищу что-то лучшее.

Ответы [ 6 ]

15 голосов
/ 09 марта 2010

Хотя мне больно это говорить, это может быть случай с никогда не популярным goto. Вот одна ссылка, которую я нашел на эту тему: http://eli.thegreenplace.net/2009/04/27/using-goto-for-error-handling-in-c/

13 голосов
/ 09 марта 2010

Я обычно пишу этот код так:

data = (big_struct *) malloc(sizeof(*data));
if(!data){
    //report allocation error
    return ...;
}

err = init_big_struct(data);
if(err){
    //handle initialization error
    return ...;
}

...

Таким образом, я избегаю вызова функций внутри if и отладка проще, потому что вы можете проверить возвращаемые значения.

3 голосов
/ 09 марта 2010

Не используйте assert в производственном коде.
В режиме отладки никогда не следует использовать assert для чего-то, что действительно может произойти (например, malloc, возвращающее NULL), скорее это следует использовать в невозможных случаях (например, индекс массива выходит за пределы в C)

Прочтите этот пост подробнее.

2 голосов
/ 09 марта 2010

Один метод, который я использовал с большим эффектом, - это метод, используемый В. Ричардом Стивенсом в Сетевом программировании Unix (код доступен для скачивания здесь . Для общих функций, которые он ожидает, чтобы преуспеть все время, и не имеет возможности обратиться за ошибкой, он переносит их, используя заглавную букву (код сжат по вертикали):

void * Malloc(size_t size) {
    void    *ptr;
    if ( (ptr = malloc(size)) == NULL)
        err_sys("malloc error");
    return(ptr);
}

err_sys здесь отображает ошибку и затем выполняет exit(1). Таким образом, вы можете просто позвонить Malloc и знать, что он выдаст ошибку, если возникнет проблема.

UNP по-прежнему остается единственной книгой, в которой, как мне кажется, у автора есть код, который проверяет возвращаемые значения всех функций, которые возможно потерпеть неудачу. Каждая другая книга гласит: «Вы должны проверить возвращаемые значения, но мы оставим это для вас позже».

0 голосов
/ 10 марта 2010

Единственное свойство группировки кода, подобное этому, заключается в том, что существует просто внешне навязанная последовательность, которой он должен следовать. Вот почему вы помещаете эти распределения в одну функцию, но это очень слабая общность. Почему некоторые люди рекомендуют отказаться от преимуществ вложенных if вне моего понимания. Вы фактически пытаетесь нанести помаду на свинью (без оскорблений) - природа кода никогда не даст ничего чистого, лучшее, что вы можете сделать, - это использовать компиляторы, помогающие отлавливать ошибки (обслуживание). Придерживайся ИМХО.

PS: если я вас еще не убедил: как будет выглядеть goto-решение, если вам придется принимать троичные решения? Если, конечно, станет еще страшнее, но Гото ???

0 голосов
/ 10 марта 2010

Я склонен к

  • Делегировать проверку ошибок для функций-оболочек (например, Стивенса)
  • В случае ошибки смоделируйте исключения, используя longjmp. (На самом деле я использую интерфейсы и реализации Дейва Хэнсона для имитации исключений.)

Другой вариант - использовать грамотное программирование Дона Кнута для управления кодом обработки ошибок или каким-либо другим видом препроцессора. Эта опция доступна, только если вы можете установить правила для вашего магазина: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...