Функция проверки ошибок С - PullRequest
       30

Функция проверки ошибок С

3 голосов
/ 14 сентября 2010

Для моего класса системного программирования мы много программируем на C и обязаны проверять ошибки большинства функций, поскольку в настоящее время мы учимся программировать с помощью pthreads.

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

Мне было интересно, кто-нибудь может показать мне, как написать функцию, которая принимает любую функцию C какпараметр, за которым следуют все обязательные параметры для этой функции, а также желаемое возвращаемое значение (в данном случае правильное) и выполняется следующее.

if(function_name(param1, param2, ...) != desired_return_value) {
    fprintf(stderr, "program_name: function_name() failed\n");
    perror("function_name(): ");
}

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

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

РЕДАКТИРОВАТЬ: В идеале это должно компилироваться по стандарту gnu99:

РЕДАКТИРОВАТЬ 2 : В ответ Джеймсу МакНеллису: ошибки в наших функциях нет (я считаю, что в этом случае), должны быть обработаны.Уведомление только должно быть предоставлено.Мы ничего не рассмотрели в отношении обработки ошибок, связанных с потоками / процессами (эта тема в двух словах).

1 Ответ

13 голосов
/ 14 сентября 2010

Написание универсального кода на C без использования макросов - не самая простая вещь.

Для (очень) базового решения с использованием макроса с переменными числами:

#define CALL_AND_CHECK(f, r, ...)                                \
    do {                                                         \
        if (f(__VA_ARGS__) != r)                                 \
        {                                                        \
            fprintf(stderr, "program_name: " #f "() failed\n");  \
            perror(#f "(): ");                                   \
        }                                                        \
    } while (0)

(см. Почему в макросах C и C ++ иногда есть бессмысленные операторы do / while и if / else? , почему используется «бессмысленный» цикл do / while)

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

...