LINUX.ORG.RU

C++ exceptions: быть или не быть

 ,


5

7

Привет!
На работе спор плюсовиков: юзать или не юзать исключения от слова совсем.

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


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

А если я оборачиваюсь в трай только там, где точно бывают исключения (только мои)? У меня много локальных траев, а не один огромный.

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

А если я оборачиваюсь в трай только там, где точно бывают исключения (только мои)? У меня много локальных траев, а не один огромный.

Молодец. А ты всегда так делаешь? А как ты отличаешь места, где исключения возможны, от тех, где они невозможны?

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

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

Так вот оно что, василий...

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

У меня в гуе нет ни одного трай кач блока и ни одного исключения не бросается.

Но что-то мне подсказывает что ты так и останешься при своём.

deep-purple ★★★★★
()
Последнее исправление: deep-purple (всего исправлений: 1)
Ответ на: комментарий от tailgunner

Молодец. А ты всегда так делаешь?

Да.

А как ты отличаешь

Очень просто — если ф-ция/метод @throwable, её вызов я оборачиваю в трай кеч. Ну не совсем только её, а весь небольшой контекст, который точно от неё зависит.

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

Ваше мнение очень важно для нас.

работай в отдельном потоке от гуя

И каким образом это решит проблему ловли исключений? Только усложнит.

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

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

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

А ты всегда так делаешь?

Да.

«Маленькая ложь рождает большое недоверие, Штирлиц» (ц)

если ф-ция/метод @throwable

Что такое «@throwable»?

её вызов я оборачиваю в трай кеч

И... что ты делаешь в catch-блоке?

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

Ваше мнение очень важно для нас

Вот я об этом.

И каким образом это решит проблему ловли исключений? Только усложнит.

Где же усложнит? Все рабочие лошадки с исключениями в отдельном потоке. Гуй не фризится. Если бросится исключение — обработка их идет в том другом потоке, он только оповестит гуй о своем состоянии когда надо, а гуй на основе этого тоже примет какой-либо вид/состояние.

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

Но чтобы бросить исключение, надо сделать if (...), так что тут мерято тогда?

Мое понимание: И чтобы вернуть return code нужен if. То есть тут паритет. А вот на стороне обработчика/catch есть разница.

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

Нет, я не вру.

Что такое «@throwable»?

То, что может бросить исключение внутри себя.

И... что ты делаешь в catch-блоке?

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

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

Что такое «@throwable»?

То, что может бросить исключение внутри себя.

Я не об этом спрашивал. Что означает конструкция @throwable в Си++ и в каком стандарте она введена? Она транзитивная?

И... что ты делаешь в catch-блоке?

Отменяю-откатываю всё что нужно отменить

И что, у тебя в этом месте всегда есть нужная информация?

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

Исключения можно не только для обработки ошибок юзать.

Например boost::thread::interrupt.

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

@throwable

Аааа, вот что тебя смутило. Ни о каких конструкциях речь не идет. Это просто ключевое словечко для документирования.

И что, у тебя в этом месте всегда есть нужная информация?

Конечно, ведь трай кеч блок локален и мал. Всё под рукой на дальности 10-15 строк кода.

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

@throwable

Это просто ключевое словечко для документирования.

А. То есть, бросает ли функция исключение, ты узнаешь из документации. Это многое проясняет.

И что, у тебя в этом месте всегда есть нужная информация?

Конечно, ведь трай кеч блок локален и мал.

Не понял, какое отношение имеет наличие информации для отката к размеру catch-блока.

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

Я понимаю что ловушка исключений будет жрать ресурсы и время. Но это очень малое время. И понимаю, что если исключение бросается хрен знает откуда из глубины, то и ловить его будут дольше. Верно? Ну так, возвраты из глубины тоже будут идти дольше. А даже если нет — при использовании исключений ты не колупаешься с ифами-ловушками возвратов и всей этой лапшой вложенных возвратов, а спокойно на одном уровне аккуратненько всё обрабатываешь.

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

deep-purple ★★★★★
()
Ответ на: комментарий от tailgunner

ты узнаешь из документации

Я сам её пишу, и ф-цию, и документацию. Будешь пользовать — читай доки как пользовать.

какое отношение имеет наличие информации для отката к размеру catch-блока

К тому, что исключение ловится ровно там же, где и бросается, поэтому, никуда никакой информации передавать о состоянии не нужно, она и так тут, под рукой, делай что надо. Тебе пример кодом чтоли привести?

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

ты узнаешь из документации

Я сам её пишу, и ф-цию, и документацию.

И никогда не ошибаешься.

Тебе пример кодом чтоли привести?

Нет. Насколько я могу судить, ты отлично документируешь код (никогда не забываешь поставить @throwable и всегда поддерживаешь их все в актуальном состоянии) и отлично проектируешь программу (в месте вызова @throwable всегда достаточно информации для исправления ошибки). Я завидую.

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

И никогда не ошибаешься

Ошибаюсь. И долго, возможно даже дольше, чем с другими подходами, ищу где же я обосрался.

отлично проектируешь программу

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

Я завидую

Не надо, это та еще морока. Тяжело.

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

И долго, возможно даже дольше, чем с другими подходами, ищу где же я обосрался.

И почему же ты не используешь другие подходы? Например, если сделать аналог Result и возвращать его, а исключения просто не использовать, @throwable просто не нужен. Или, например, использовать упомянутый выше Expected.

уже раза четыре больше половины переписывал

Один работаешь?

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

И почему же ты не используешь другие подходы?

Мне этот нравится.

возвращать

Не хочу лапши из глубины возвратов. Гиблое дело.

Expected

Какое-то оно ... восьминогий семиглаз. Вобщем мне мой подход нравится, даже если для кого-то он как тот же семиглаз.

Один работаешь?

Да, поделка моя, пилю один. Сам себе хозяин. Сам себе на грабли наступатель. Обкатываю жи подход к проектированию, так сказать. Как допилю — выложу на ЛОР. Пацанам на поржать.

deep-purple ★★★★★
()
Ответ на: комментарий от RazrFalcon

Считай что про отсутствие фризов гуя я вообще не писал.

По исключениям в отдельном треде, но не в гуе, что скажешь?

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

Так ничего не меняется. Меня бесит то, что любая функция может бросить исключение и это никак нельзя отловить на этапе компиляции.

При этом в rust это в целом можно.

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

В теории (всмысле формальной теории ЯП [1]) исключение ничем от резалт монады не отличается. То и другое — первоклассные эффекты, это буквально одно и то же (точнее монады и эффекты в целом одно, достаточно посмотреть на монадическую и «эффектную» реализацию стэйт [2]). Разница в реализации, что какой оверхед вносит.

В крестах то и другое реализовано одинаково убого: резалт криво и небезопасно, так как нет нормальных тип-сумм, исключения никак не отражаются в системе типов (хотя явно безопаснее и более sound, чем недоразумение под названием std::variant и ему подобные), так что даже и не скажешь, бросает тот или иной код исключение или нет (вроде же хотели, но не осилили). Чсх у людей получилось бэкпортировать типизированные эффекты в окамл [3], в кресты тоже можно бы было, так как вывод типов вроде как есть. В лиспе вон выкинутое исключение хотя бы динамически можно пофиксить и продолжить выполнение, плюс во многих языках есть стандартные обработчики.

[1] https://www.cs.uoregon.edu/research/summerschool/summer18/topics.php#Bauer

[2] https://github.com/ocamllabs/ocaml-effects-tutorial/blob/master/sources/solve...

[3] https://www.youtube.com/watch?v=z8SI7WBtlcA

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

Егегей, всем спасибо за потрясающие коментарии и массу толкового стафа!

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

Вообще в секундах мерять не очень. Лучше уж в циклах для конкретных архитектур. Если найду тесты, то переделаю.

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

ну да, логично. в тиках проца, в циклах. но ещё сами тесты должны быть грамотно написаны.

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

В теории (всмысле формальной теории ЯП [1]) исключение ничем от резалт монады не отличается

Но мы-то говорим о реальности. Более того, о реальности, наблюдаемой в Си++.

В крестах то и другое реализовано одинаково убого: резалт криво и небезопасно

О какой реализации Result речь и в чем ее небезопасность?

как нет нормальных тип-сумм

Нормальных с точки зрения «формальной теории ЯП»?

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

Гугл в своём Style Guide отказался от исключений по этой причине

Сенсация! Аж сам гугл отказался. Я не прикалываюсь, просто это действительно показатель. Там то вроде не лохи работают.

https://google.github.io/styleguide/cppguide.html#Exceptions более точная ссылка на самую мякотку. We do not use C++ exceptions :)

I-Love-Microsoft ★★★★★
()
Последнее исправление: I-Love-Microsoft (всего исправлений: 2)
Ответ на: комментарий от d_a

Вот мне тож интересно, ТС отметил solved, но смешно - что же он решил, кто победил, почему? Наверное я его убедил. Посоны, экзепшены нинужны.

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

все намного проще, выперли бестолковых цепепешников споривших нужны ексепшены или нет и взяли толковых цепепешников которые молча решили что надо а что нет ))))

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

Нормальных с точки зрения «формальной теории ЯП»?

Нормальных с точки зрения статической проверки на exhaustiveness.

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

Можно посмотреть?

Можно, но смотреть особо не на что - макрос генерирует enum-тег, специфичный для sum type, в роли match используется switch, и GCC выдает предупреждение, когда не все варианты тега использованы.

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

Понятно, match по tag_of? А как поля из конструктора вытаскивать? Там есть статические гарантии, чтобы не вытащить поля не от того тэга?

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

А как поля из конструктора вытаскивать?

Поля конкретного варианта вытаскиваются через as<T>.

Там есть статические гарантии, чтобы не вытащить поля не от того тэга?

Не понял, статическая гарантия чего именно. Поля не от того тега вытащить невозможно.

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

через as<T>

T не выводится компилятором, да? Почему у меня собралось такое без ворнингов:

    SumType<int,float,std::string> x = std::string("test");
    std::cout << x.as<int>() << std::endl;
Freyr69 ★★★
()
Последнее исправление: Freyr69 (всего исправлений: 2)
Ответ на: комментарий от RazrFalcon

Подход Qt тоже спорный. Получается простой и понятный код, но надёжность страдает.

Я один вижу взаимоисключающие параграфы?

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

А тут и невозможны статичные гарантии. Только с паттерн-матчингом/визитором.

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

T не выводится компилятором, да?

А что должно выводится? Все типы указаны же явно. Если речь о статической гарантии того, что в as<T>() укзан T, сооветствующий содержимому объекта, то ее нет - для этого нужно, чтобы компилятор понимал, что такое sum type, и умел настоящий match.

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