LINUX.ORG.RU

Расскажите о философии их использования

 ,


4

5

Уже много дней пишу на C++, но так сложилось, что в проектах, в которых я участвую, исключения не используются.

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

Приветствуются ссылки на статьи на русском и английском языках.

Так же можете оставлять свое собственное мнение о практике и философии использования исключений в с++ коде.

★★★★★

Последнее исправление: cetjs2 (всего исправлений: 1)

Ответ на: комментарий от anonymous

во первых ексепшны это потенциально текущий софт. даже со смартпоинтерами.

во вторых ексепшны в С++ это доплнительный рантайм на поиск хендлера.

в третьих случайно просраный ексепшн тормознет весь софт, что не очень хорошо в продакшне.

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

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

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

Использовать исключения с++ кроме как для обработки аварийной ситуации в программе (с дальнейшем ее завершением) не имеет смысла. Иначе получается управление control flow, для чего исключения не были задуманы. Лучше ассерт вызвать.
Другое дело либа, где хз как ей будут пользоваться при наступлении исключительной ситуации. Там вполне уместно использование эксепшенов. Примеров тому куча. stl, boost.

nerdogeek
()
Ответ на: комментарий от anonymous

Ну да, в продакшене лучше что бы просто упало с окном программа выполнила недопустимую операцию. :)

Недопустимая операция через try не ловится, такие вещи сигналом посылаются, как и сегфолт.

А вот непроверенный код возврата в худшем случае вызовет варнинг, а в продакшене - не будет выполено какое-то действие. Непойманное исключение вызовет крах.

quiet_readonly ★★★★
()
Последнее исправление: quiet_readonly (всего исправлений: 1)
Ответ на: комментарий от nerdogeek

Скажи, у тебя все программы завершаются с коредампом, если например не могут найти важный для дальнейшей работы файл? Не просто аварийно, а именно с коркой? Ты же об этом писал в том сообщении? По поводу либ, а ты попробуй считать всю свою программу библиотекой, которая используется в main.cpp.

anonymous
()
Ответ на: комментарий от quiet_readonly

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

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

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

:DDD

Как?

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

Обработка ситуации отсутствия файла не требует вызова эксепшена, т.к. обработка такой ситуации должна быть на месте, в той же функции. Коредамп создавать не нужно в данном случае, достаточно кинуть месагу в лог. А вот если неожиданно пришел nullptr в аргументе ф-ии, то коредамп поможет обнаружить причину.

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

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

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

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

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

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

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

А потом, начинается медленный подъем по стеку возвратов через все 100500 функций...

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

Можно «считать всю свою программу библиотекой, которая используется в main.cpp»... но зачем? эксепшены - костыль. Еще и опасный. Типа, я хз что делать, файла нет, значит пусть кто-нить что-нить решит за меня - кидаю эксепшон.

nerdogeek
()
Ответ на: комментарий от anonymous

Почему вы приводите в пример new? Ни один даже самый злостный противник исключений не будет использовать new (nothrow) просто из принципа.

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

Вот об этом и речь. Что в определенных местах исключения очень хороши и удобны. И нет никакой причины отказываться от них вообще, только из-за комплексов. :)

anonymous
()
Ответ на: комментарий от quiet_readonly

Это самый простой пример, который показывает, что падение может быть совершенно в другом месте, от места некачественной проверки.

anonymous
()

КостылиЭксепшоны - клёво!
reinterpet_cast и const_cast тоже.

anonymous
()
Ответ на: комментарий от nerdogeek

эксепшены - костыль. Еще и опасный.

А под кроватью живет страшный Бука. :)

Да функция нижнего уровня скорее всего не знает, как исправить ситуацию. Детский пример, ты пытаешься создать объект конфигурации, он должен прочитать файл с конфигурацией. По одному пути файла нет -> исключение, еще один путь к файлу, файл имеет неизвестный формат -> исключение, ты спокойно создал объект от класса DefaultConfig (ему не нужен никакой файл). Тебе не нужно ничего проверять по пути выполнения функция, а потом поднимать в самый верх код ошибки.

anonymous
()
Ответ на: комментарий от nerdogeek

Ах эти крайности, крайности, крайности... ;) Гулять, так гулять, и циклы предлагаю на исключениях делать.

anonymous
()
Ответ на: комментарий от nerdogeek

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

dmfd
()
Ответ на: комментарий от i-rinat

Ой...я думал, что тут шутят, а тут вон чего.

Хотя любопытно, надо будет на досуге почитать. Спасибо за интересную ссылочку.

DeVliegendeHollander ★★
()

можешь ещё считать, что исключение это обратная сторона медали reference и отсутствия NUL-объекта в языке. В ситуации когда метод должен вернуть ссылку или корректный объект, но физически не может этого сделать, другого способа прекратить всё это безобразие нет :)

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

Я как-то видел выход из вложенного цикла на исключениях

я видел чтение строки из сокета в буфер, когда любой символ кроме \n вызывал исключение. «строка не завершена, работать с ней пока нельзя, в UML это возврат в пред.состояние, поэтому exception»

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

Что мешает вернуть 0 или инвалидный (но корректный) объект?

отсутствие инвалидного (но корректного) объекта :) Отнюдь не во всех классах такое возможно.

MKuznetsov ★★★★★
()
Ответ на: комментарий от i-rinat

Оптимизацией в том случае был бы инлайн функции и break. Исключения никакой оптимизирующей магии там не совершили.

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

Оптимизацией в том случае был бы инлайн функции и break. Исключения никакой оптимизирующей магии там не совершили.

Твоих знаний очень не хватает в том проекте. Они там за крохи производительности бьются, а ты на ЛОРе прохлаждаешься.

Подозреваю, что реальный код там посложнее примеров. Если весь рекомпилятор делать так, как ты предлагаешь, мозг лопнет. Сложностью надо как-то управлять.

i-rinat ★★★★★
()
Ответ на: комментарий от anonymous

То, что ты никогда так и не узнаешь, почему объект не был создан. И ошибка вида „произошла какая-то ошибка“ несут столько же информации, как и слова „интерполяция пирожка“.

Кроме того это

int f1()
{
	int ret;
	ret = do_that();
	if (ret < 0) {
		return ret;
	}

	ret = do_this();
	if (ret < 0) {
		undo_that();
		return ret;
	}

	ret = do_formatC();
	if (ret < 0) {
		undo_this();
		undo_that();
		return ret;
	}
	return 0;
}
говно, а это
int f2() try
{
	auto_ptr <RetRef> r1 = do_that();
	auto_ptr <RetRef> r2 = do_this();
	do_formatC();
	return 0;
} catch (int ret) {
	return ret;
}
нет

nanoolinux ★★★★
()
Последнее исправление: nanoolinux (всего исправлений: 3)
Ответ на: комментарий от nanoolinux
int f1()
{
    int ret;
    ret = do_that();
    if (ret < 0)
        return ret;

    ret = do_this();
    if (ret < 0)
        goto oops_1;

    ret = do_formatC();
    if (ret < 0)
        goto oops_2;

    return 0;
oops_2:
    undo_this();
oops_1:
    undo_that();
    return ret;
}
i-rinat ★★★★★
()
Ответ на: комментарий от nanoolinux

Кроме того это

У тебя си головного мозга.

И ошибка вида „произошла какая-то ошибка“

Кто мешает указать какая именно произошла ошибка?

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

Ты не здоров или пьян. Я писал, что код с проверкой ret после каждого чиха - говно. Ты утвеждаешь что

У тебя си головного мозга.

и

if (ret != 0) {goto errN;}

Я тебе уже сказал, что так на С++ пишут только люди с СГМ.

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

Что мешает вернуть 0 или инвалидный (но корректный) объект?

То, что 0 несёт инфу только о том, что ошибка произошла. Что за ошибка - ни слова. инвалидный объект надо ещё проверить на валидность где-то в другом месте, и в 99% случаев (это из моего опыта) этого никто не делает. В результате - сегфолт рано или поздно, думаю не стоит объяснять почему.

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

Я писал, что код с проверкой ret после каждого чиха - говно.

Ты не совсем это писал, ты привел пример говнокода, в котором в том числе и проверки после каждого чиха.
Проверки это вполне окей, а вот то, как ты их обрабатывал — говно в стиле неуклюжего си, после чего кто-то привел пример с говном стиле нормального си.

Свой пример с try/catch ты же специально упростил. В реальности тебе точно так же потребуются множественные проверки на тип исключения или на его код ошибки, от этого никуда не денешься. А то и вовсе придется оборачивать «каждый чих» в try/catch отдельно.

anonymous
()
Ответ на: комментарий от nanoolinux

То, что 0 несёт инфу только о том, что ошибка произошла.

О боги, ну что ты как маленький? Ты можешь сохранить ошибку в любом другом месте. Тот, кто получит 0, если захочет, заглянет в это место.

В результате - сегфолт рано или поздно, думаю не стоит объяснять почему.

У тебя неправильные инвалидные объекты, если они вызывают «сегфолт рано или поздно». Ты уверен, что ты можешь в С++?

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

Свой пример с try/catch ты же специально упростил. В >реальности тебе точно так же потребуются множественные >проверки на тип исключения или на его код ошибки, от этого >никуда не денешься. А то и вовсе придется оборачивать «каждый >чих» в try/catch отдельно.

4.2

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

Ты можешь сохранить ошибку в любом другом месте.

Привельно. Больше глобальных переменных, хороших и разных.

nanoolinux ★★★★
()
Ответ на: комментарий от i-rinat

Они там за крохи производительности бьются

В статье говорятся правильные слова про оптимизацию hot spots, а вот с самой оптимизацией неувязка. Там в цикле дёргается функция. Если уж в самом деле "биться за крохи производительности", то если функция лёгкая, её стоит заинлайнить и тогда вместо исключений можно использовать break. Если функция сложная, то не о том надо думать, как один if убрать.

Использование исключений для управления выполнением программы - костыль и зло.

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

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

Ты всё правильно говоришь, и спорить дальше, не зная кода, я не могу. Единственно что, я верю, что если ребята из pcsx2 так сделали, на то были веские причины.

Использование исключений для управления выполнением программы - костыль и зло.

когда дело доходит до критичных к скорости участков, в ход идут костыли.

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