Страницы

Поиск по вопросам

пятница, 13 декабря 2019 г.

Лучший способ сказать о ошибке в Си

#c


Пишу небольшую библиотеку, с функциями, которыми кто-то будет пользоваться. В функциях
случаются ошибки, о которых нужно каким-то образом сообщить. Казалось бы — банальная
вещь, но везде сделано по-разному. Мне интересны преимущества каждого способа, их для
меня пока три:  


Возвращать true или false. Пользователь библиотеки сам будет проверять возвращаемое
значение и в зависимости от него выводить сообщение об ошибке.
Самостоятельно в функциях библиотеки сообщать в подробностях о всех предупреждениях
или ошибках, exit'ом убивать приложение, ничего не возвращая.
Возвращать true или false, но при этом ещё и записывать ошибку в специальный буфер.
Пользователь библиотеки может узнать об ошибке, вызвав функцию GetError(). Так сделано
в SDL.


По-моему, лучше всего использовать второй способ, но зачем тогда SDL усложняет всё
своими GetError/SetError? Зачем тот же EGL возвращает только код ошибки? Прошу сказать
о плюсах/минусах того или иного способа, они ведь наверняка есть.
    


Ответы

Ответ 1



При написании библиотечного кода надо иметь в виду, что пользоваться этим кодом могут совершенно разные приложения. Поэтому вывод куда-либо явного сообщения об ошибке может просто не сработать, т.к. этого "куда-либо" может вовсе не существовать в текущем окружении (об этом уже упомянул @AntonShchyrov в своем ответе). Более того, язык сообщения может быть вовсе не подходящим для пользователя. Наиболее подходящим вариантом будет предоставить дополнительную функцию или переменную, откуда можно получить код/текст последней ошибки. Существующие варианты такого подхода это errno, GetLastError и т.п. В этом случае, пользователь библиотеки может сам решить куда ему следует (и следует ли вообще) выводить сообщение об ошибке. Отсюда же вытекает и решение о недопустимости вызова exit из библиотечного кода. По крайней мере, если нет соответствующей функции в библиотеке, которая меняет это поведение (по умолчанию никаких активных exit быть не должно). Пользователю может быть вообще хочется наплевать на обработку ошибок и просто работать дальше, а библиотека рушит ему всё приложение из N потоков на корню. Возвращать из каждой функции признак успешности её выполнения через return может быть не совсем удобно, т.к. в первую очередь функция должна возвращать то, на что она заточена, а не признак ошибки или код возврата. Для примера, представьте, как будет выглядеть функция типа strlen в таком случае и насколько удобно будет ей пользоваться при этом. В любом случае, способы оповещения пользователя библиотеки об ошибочных ситуациях должны быть чётко прописаны в руководстве.

Ответ 2



Нет. Лучше всего третий способ. Куда во втором способе Вы будете выводить сообщение? В консоль? А если библиотека запущена из оконного приложения? В MessageBox/окно? А если библиотека используется в службе или потоке без очереди сообщений?

Комментариев нет:

Отправить комментарий