LINUX.ORG.RU

[C] Лучшие практики обработки ошибок


0

0

Какие вы применяете методы обработки ошибок? Имеется ввиду:

1. ассерты,

2.проверки всех входных параметров на корректность, проверки только некоторых из них;

3. полной проверки на корректность или только проверка на неравенство NULL, например;

4. использование setjmp/longjmp (или макросов, эмулирующих исключения), возврат кодов и/или установка глобальной переменной типа errno или же установка значения переменной в структуре (типа как в либах libconfig, libzip, etc).

5. Если устанавливаете код ошибки внутри переменной, то предлагаете только defin'ы (int'ы) для соот. кодов или же функция типа

const char * print_err_info(int errcode) 
, которая возвращает строку с информацией об ошибке.

6. Если 5 вариант имеет место, то строка об ошибке содержит абстрактную информацию типа «Some error occured» (и является статической констатной в сегменте данных) или же строка создается sprintf'ом со всем параметрами, которые могли вызвать ошибку.

Если что пропустил - дополните. Интересует полный спектр всех возможных способов проверок и их применяемость в конкретной ситуации.

★★

Ассерты(разумеется, только в debug режиме) + проверка параметров приходящих извне. Возвращаемое значение - enum.

kulti ★★ ()

Это смотря чо пишем, а вообще каждый метод для своей ситуации

Boy_from_Jungle ★★★★ ()

1) Используйте assert только для дебага. Никогда не используйте его в продакшн-коде. Компилятор имеет право и будет убирать assert при определенных настройках компиляции. Хотите проверить ограничения - используйте if и возвращайте ошибку. Код обязан продолжать корректно работать даже когда все assert будут вырезаны.

2) Зависит от контракта функции.

3) Зависит от контракта функции.

4) Воспользуетесь setjmp и порадуетесь непереносимой и плохо поддерживаемой программе. Глобальные переменные тоже лучше избегать.

5) enum'ы для кодов ошибок + документация. Использующий код сам разберется что выводить пользователю.

6) Зависит от ошибки и насколько много простому пользователю нужно о ней знать.

Стандартный способ работать с ошибками в Си - goto для освобождения ресурсов + возврат кода ошибки каким-нибудь удобным функции способом.

ntp ()
Ответ на: комментарий от bk_

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

osox ()
Ответ на: комментарий от bk_

вот например в win32 такая схема при создании потока создается сопоставленная с ним структура в ней есть поле которое хранит код последней ошибки в потоке которое устанавливают различные функции если функция потерпела неудачу она устанавливает специфичный код в это поле и просто возвращает 0 а если успех то 1 если нужна более обширная информация об ошибке вызываеш getlasterror она считывает код с этого поля потом этот код можно так же сконвертировать в строку formatmessage похоже на тот же подход что и в crt

osox ()

В своем коде не вижу смысла все усложнять и изобретать механизмы обработки ошибок. Возврат кода ошибки а потом по таблице искать строку, зачем? если можно сразу написать в лог/stderr то, что хотели. Если у вас конечно не, что либо либо-подобное.

Главная сложность это восстановление после некритичной ошибки, когда нельзя сделать exit(1). Хорошо, что не часто с ними приходиться работать. Как это лучше обработать не знаю, стараюсь избегать обработки таких ошибок или уменьшать их сложность.

amaora ★★ ()
Ответ на: комментарий от amaora

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

bk_ ★★ ()

+ до кучи использую tdd и unit-testing (CUnit)

shty ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.