Обработка ошибок в коде C - PullRequest
137 голосов
/ 22 декабря 2008

Что вы считаете «наилучшей практикой», когда речь идет об обработке ошибок согласованным способом в библиотеке C.

Есть два способа, о которых я думал:

Всегда возвращайте код ошибки. Типичная функция будет выглядеть так:

MYAPI_ERROR getObjectSize(MYAPIHandle h, int* returnedSize);

Всегда используйте подход указателя ошибки:

int getObjectSize(MYAPIHandle h, MYAPI_ERROR* returnedError);

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

int size;
if(getObjectSize(h, &size) != MYAPI_SUCCESS) {
  // Error handling
}

Что выглядит лучше, чем код обработки ошибок здесь.

MYAPIError error;
int size;
size = getObjectSize(h, &error);
if(error != MYAPI_SUCCESS) {
    // Error handling
}

Однако я думаю, что использование возвращаемого значения для возврата данных делает код более читабельным. Очевидно, что что-то было записано в переменную размера во втором примере.

У вас есть идеи, почему я должен предпочесть какой-либо из этих подходов или, возможно, смешать их или использовать что-то еще? Я не фанат глобальных состояний ошибок, так как это делает многопоточное использование библиотеки более болезненным.

EDIT: Особые идеи C ++ по этому вопросу также было бы интересно услышать, если они не связаны с исключениями, поскольку в данный момент это не вариант для меня ...

Ответы [ 21 ]

0 голосов
/ 01 марта 2018

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

if( !doit(a, b, c, &errcode) )
{   (* handle *)
    (* thine  *)
    (* error  *)
}

Когда у вас много проверок на ошибки, это небольшое упрощение действительно помогает.

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