writing library | поддержка отказа от исключений
От: Sm0ke Россия ksi
Дата: 09.08.23 11:20
Оценка:
В некоторых проектах разработчики принимают решение полностью отказаться от механизма throw exceptions
путём задания соотв. опции компилятора

С точки зрения разработчика библиотеки
(который не знает в каких проектах возможно использование его либы)
на этот случай приходится позаботиться о выбираемых policy для библиотечных классов

Я хочу спросить вот о чём: Как в крупных проектах обрабатываются ситуации скажем при выделении памяти? (Вопрос 1)
Не будете же писать по старинке на каждый чих if( p == nullptr )
По идее должен быть некий обобщённый механизм, чтобы все аллокации происходили через него
(Можно к примеру писать std::source_location в лог, да по всякому)

Мне не приходилось пока участвовать в проектах с откл. исключениями, вот и спрашиваю.

А на счёт некоторой либы уточнение ~ Память может быть не_выделена по одной из двух причин:
* нехватка памяти в компе
* перед вызовом аллокации не была произведена предварительная инициализация

Либа рассчитана и на обработку ошибок с исключениями и без.
С исключениями просто кидаем std::bad_alloc либо e_unready

А вот как лучше сделать, когда выбрано полиси без исключений? (Вопрос 2)
Самое простое это конечно тупо использовать nullptr в обоих случаях, но как-то не айс

upd: Думаю лучше действительно использовать nullptr, плюс добавить static метод was_unready()

Ну понятно, что полиси с исключениями придётся обернуть в препроцессор #ifndef ...
А кстати как корректно узнать, что они отключены у компилятора? (Вопрос 3)
Re: writing library | поддержка отказа от исключений
От: kov_serg Россия  
Дата: 09.08.23 11:32
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S>В некоторых проектах разработчики принимают решение полностью отказаться от механизма throw exceptions

S>путём задания соотв. опции компилятора
это видимо в embeded итмеется ввиду?

S>С точки зрения разработчика библиотеки

S>(который не знает в каких проектах возможно использование его либы)
S>на этот случай приходится позаботиться о выбираемых policy для библиотечных классов

S>Я хочу спросить вот о чём: Как в крупных проектах обрабатываются ситуации скажем при выделении памяти? (Вопрос 1)

S>Не будете же писать по старинке на каждый чих if( p == nullptr )
S>По идее должен быть некий обобщённый механизм, чтобы все аллокации происходили через него
S>(Можно к примеру писать std::source_location в лог, да по всякому)
так для библиотеки делается внешний интерфейс или сишный или типа com
а внутри можно пользоваться исключениями и всем остальным, лишь бы наружу оно не вылазило.
Re: writing library | поддержка отказа от исключений
От: Chorkov Россия  
Дата: 09.08.23 12:00
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S>А кстати как корректно узнать, что они отключены у компилятора? (Вопрос 3)


См. макрос __cpp_exceptions, (он должен быть в С++20).

Или придется смотреть макросы для каждого из доступных компиляторов отдельно.
Например _HAS_EXCEPTIONS для MSVC.

Но лучше, пусть пользователь явно скажет системе сборки хочет он бросание исключений данной библиотекой или нет.
Возможно, он предпочтет (от вашей конкретной либы), получать не исключения а коды возврата, даже при наличии исключений у компилятора.
Re[2]: writing library | поддержка отказа от исключений
От: Sm0ke Россия ksi
Дата: 09.08.23 12:41
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>это видимо в embeded итмеется ввиду?

Не обязательно

_>так для библиотеки делается внешний интерфейс

_>или сишный
Нет, полностью плюсовая либа

_>или типа com

Зачем?

_>а внутри можно пользоваться исключениями и всем остальным, лишь бы наружу оно не вылазило.

При отключении компилятором исключений даже внутри нельзя. Это не dll. Просто модуль ixx
Ни catch не throw нельзя

Придётся полиси классы оборачивать #ifndef, но каким?
Re[2]: writing library | поддержка отказа от исключений
От: Sm0ke Россия ksi
Дата: 09.08.23 13:28
Оценка:
Здравствуйте, Chorkov, Вы писали:

C>Здравствуйте, Sm0ke, Вы писали:


S>>А кстати как корректно узнать, что они отключены у компилятора? (Вопрос 3)


C>См. макрос __cpp_exceptions, (он должен быть в С++20).


Спасибо, это подойдёт.
Не нашёл правда инфу о нём на cppref

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


Я и хочу сделать полиси классы отдельно (с исключениями и без)
Классы с исключениями оберну в #ifdef __cpp_exceptions, чтобы их вообще не было в этом случае

C>Возможно, он предпочтет (от вашей конкретной либы), получать не исключения а коды возврата, даже при наличии исключений у компилятора.


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

Возвращать лишние данные при throw_policy тоже как-то некрасиво.

По сути возвращаемого значения может и не быть.
А смарт поинтер класс (RAII), который в конструкторе запрашивает память.
В случае неудачи хранит nullptr, а от полиси зависит будет ли исключение из конструктора брошено.

Но вот как лучше отделить причину неудачи (закончилась память, или не было вызвано средство инициализации)
Не хранить же статусы в самом классе, да? Вот думаю сделать статический метод was_unready()

Собственно инициализация вызывается только один раз, сразу на все любые типы, но для каждой dll/exe отдельно
Отредактировано 09.08.2023 13:30 Sm0ke . Предыдущая версия . Еще …
Отредактировано 09.08.2023 13:29 Sm0ke . Предыдущая версия .
Re: writing library | поддержка отказа от исключений
От: Zhendos  
Дата: 09.08.23 15:30
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S>Я хочу спросить вот о чём: Как в крупных проектах обрабатываются ситуации скажем при выделении памяти? (Вопрос 1)

S>Не будете же писать по старинке на каждый чих if( p == nullptr )

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

Кстати есть специальная перегрузка для "new" для этого случая,
начиная с C++11.

int* p = new(std::nothrow) int[100000000ul]; // non-throwing overload
Re[2]: writing library | поддержка отказа от исключений
От: Sm0ke Россия ksi
Дата: 09.08.23 16:04
Оценка:
Здравствуйте, Zhendos, Вы писали:

Z>Здравствуйте, Sm0ke, Вы писали:


S>>Я хочу спросить вот о чём: Как в крупных проектах обрабатываются ситуации скажем при выделении памяти? (Вопрос 1)

S>>Не будете же писать по старинке на каждый чих if( p == nullptr )

Z>А чем это от всех остальных случаев отличается? Нет исключений,

Z>нужно будет везде проверять результат выполнения.

Ожидался ответ:
Вот тут мы используем optional, а тут expected,
Или: А это мы не используем, потому что ...
Или: У нас есть универсальная проверялка, которая сама подсасывает source_lacation, и в случае таких ошибках у нас лог + terminate(), а в таких то то и тото

Короче примеры из реальных проектов

----
Z>Кстати есть специальная перегрузка для "new" для этого случая,
Z>начиная с C++11.

Z>
Z>int* p = new(std::nothrow) int[100000000ul]; // non-throwing overload
Z>

----

о_о
Re[3]: writing library | поддержка отказа от исключений
От: so5team https://stiffstream.com
Дата: 09.08.23 17:07
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S>Короче примеры из реальных проектов


Так посмотрите на Asio, там есть методы/функции, которые принимают ссылку на неконстантный error_code. Такие функции не бросают исключений, возвращают признак ошибки через этот out-параметр. Те же функции/методы, которые не имеют подобного out-параметра, бросают исключения.

-----

Если вы собираетесь делать библиотеку, которая предназначена для использования с --no-exceptions, то как вы планируете обходится без стандартных контейнеров из STL? Будете использовать самописные аналоги или какой-нибудь ETL C++?
Re[3]: writing library | поддержка отказа от исключений
От: kov_serg Россия  
Дата: 09.08.23 18:19
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S>Нет, полностью плюсовая либа

Тогда зачем?

S>Ни catch не throw нельзя

Используйте другие механизмы
Re[4]: writing library | поддержка отказа от исключений
От: Sm0ke Россия ksi
Дата: 09.08.23 18:55
Оценка:
Здравствуйте, so5team, Вы писали:

S>Если вы собираетесь делать библиотеку, которая предназначена для использования с --no-exceptions, то как вы планируете обходится без стандартных контейнеров из STL? Будете использовать самописные аналоги или какой-нибудь ETL C++?


Предназначена для использования как с no-exceptions, так и без
Да, самописные аналоги

Если не заброшу, конечно)
Re: writing library | поддержка отказа от исключений
От: sergii.p  
Дата: 10.08.23 07:57
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S>Как в крупных проектах обрабатываются ситуации скажем при выделении памяти? (Вопрос 1)


конструирование с помощью статических функций

struct Foo {
    static std::expected<Foo, Err> create() noexcept;
    std::expected<int, Err> foo() const noexcept;
    int bar() const noexcept;
private:
    Foo();
};


S>Не будете же писать по старинке на каждый чих if( p == nullptr )


можно не по старинке, можно модно-молодёжно
auto res = Foo::create()
    .map(Foo::bar)
    .and_then(Foo::foo)
    .map_err(log_err);


S>А вот как лучше сделать, когда выбрано полиси без исключений? (Вопрос 2)


std::expected. Стандартный правда бросает исключения, но можно написать свой аналог.
Re: writing library | поддержка отказа от исключений
От: PM  
Дата: 10.08.23 08:02
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S>В некоторых проектах разработчики принимают решение полностью отказаться от механизма throw exceptions

S>путём задания соотв. опции компилятора

S>С точки зрения разработчика библиотеки

S>(который не знает в каких проектах возможно использование его либы)
S>на этот случай приходится позаботиться о выбираемых policy для библиотечных классов

По моему скромному мнению, одновременное `-fno-exceptions` и использование стандартной библиотеки — это шиза в проекте.

Вы у себя в библиотеке можете использовать другие методы сигнализации об ошибках: `std::error_code`, `std::expected` вместо бросания исключений. Однако если при этом вы используете стандартные вектор или строки, то ловить bad_alloc — не ваша забота.
Re[2]: writing library | поддержка отказа от исключений
От: Кодт Россия  
Дата: 10.08.23 23:40
Оценка: +1
Здравствуйте, PM, Вы писали:

PM>По моему скромному мнению, одновременное `-fno-exceptions` и использование стандартной библиотеки — это шиза в проекте.


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

Код, который боится, что из каждого std::cout << std::string("aaa!!!") может вылететь исключение (включая bad_alloc), — и обмазывается по этому случаю try-catch'ами, пусть даже и единственным, в main(), — это немножко паранойя.

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

С тем же bad_alloc — он возникает в 3 случаях
— взяли слишком слабое железо, недостаточное для данной задачи
— написали слишком прожорливый код
— где-то есть баг — то ли утечка, то ли напутали с заказанным размером, то ли обстреляли кучу

В отладочной / дорелизной версии программно-аппаратного комплекса — надо чинить, а не разматывать стек.
В релизной / продакшен версии — чинить поздно, но изоляция ошибки может быть на уровне графа процессов, а не на уровне стека функций. Процесс-исполнитель упал, процесс-дирижёр его перезапустил (или не перезапустил).
Перекуём баги на фичи!
Re[3]: writing library | поддержка отказа от исключений
От: so5team https://stiffstream.com
Дата: 11.08.23 05:10
Оценка:
Здравствуйте, Кодт, Вы писали:

К>По моему практическому опыту, отказ от исключений в пользу немедленного креша — вполне рабочий подход.

К>Просто надо добиться того, чтобы программа не пыталась кидать исключения.

К>...


К>В отладочной / дорелизной версии программно-аппаратного комплекса — надо чинить, а не разматывать стек.

К>В релизной / продакшен версии — чинить поздно, но изоляция ошибки может быть на уровне графа процессов, а не на уровне стека функций. Процесс-исполнитель упал, процесс-дирижёр его перезапустил (или не перезапустил).

Сразу видно человека, который server-side занимается

И нет, Chrome, у которого регулярно падают вкладки, не есть хороший пример того, как падают процессы в графах с рестартами от супервизора.
Re[4]: writing library | поддержка отказа от исключений
От: Кодт Россия  
Дата: 11.08.23 23:16
Оценка: +2
Здравствуйте, so5team, Вы писали:

S>Сразу видно человека, который server-side занимается


S>И нет, Chrome, у которого регулярно падают вкладки, не есть хороший пример того, как падают процессы в графах с рестартами от супервизора.


Как человек, писавший яндекс-браузер (форк хрома), имею сказать!
Изоляция процессов — это как раз хороший подход. По нескольким причинам.

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

Во-вторых, борьба с невосстановимыми ошибками. Прежде всего, с зажором ресурсов, утечками и зависаниями в рендерере и яваскрипте.
Утечка — это очень подлая проблема. Если она произошла, то исключение bad_alloc возникает не в момент собственно утечки (а этгго момента может и не быть, просто плавный зажор памяти), а когда уже всё поздно. Ну и чего там разматывать, на какую глубину стека функций и на какой объём графа данных?

В-третьих, отказ от пользовательских исключений — это меньший размер кода, какие-то копеечки производительности (а для графического движка эти копеечки имеют критическое значение) и специфическая дисциплина программирования. Пропадает "теневая система типов".
На самом деле, объём писанины при этом вырастает не очень сильно. Потому что весь код, который должен не взирать на исключения, — он таковым и остаётся. Мест, где реально надо смотреть, обрабатывать и пробрасывать флажки ошибок, немного.

Ещё надо помнить, что браузер — это сплошные UI-колбеки и рабочие потоки. И неконтролируемые исключения могут устроить там погром и молнию. Пробрасывать исключение через границы колбеков и потоков — дело творческое, мягко говоря. Обмазывать каждый колбек защитным try-catch — это плюс к писанине, вместо экономии. Обмазывать UI-фреймворк, делая его устойчивым к забытым исключениям в колбеках... а в чём эта устойчивость будет выражаться? В том, что программа не сразу рухнет по terminate, а проглотит исключение, и переведёт неопределённое поведение на следующий, смысловой уровень? Пусть пользователь сам поймёт, что браузер давно уже творит какую-то дичь, и пристрелит его через менеджер задач?

Так что при всей изящности и красоте механизма исключений, я очень хорошо понимаю, зачем от них отказываются.

Хотя и проблемы, связанные с отказом от исключений, я тоже видал и большой ложкой хлебал. Но не в хромиуме.
Перекуём баги на фичи!
Re[4]: writing library | поддержка отказа от исключений
От: CreatorCray  
Дата: 12.08.23 00:59
Оценка:
Здравствуйте, so5team, Вы писали:

S>Chrome, у которого регулярно падают вкладки

Да в общем то очень нерегулярно.
Что ты с ним делаешь эдакого?
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[5]: writing library | поддержка отказа от исключений
От: so5team https://stiffstream.com
Дата: 12.08.23 05:40
Оценка: 4 (1)
Здравствуйте, CreatorCray, Вы писали:

S>>Chrome, у которого регулярно падают вкладки

CC>Да в общем то очень нерегулярно.
CC>Что ты с ним делаешь эдакого?

Открываешь Google Drive, затем открываешь один или два документа оттуда (они открываются в новых вкладках), оставляешь вкладку с Google Drive открытой, но в фоне, начинаешь работать с открытыми документами. С вероятностью больше 50% в течении часа-двух вкладка с Google Drive упадет.
Re[5]: writing library | поддержка отказа от исключений
От: so5team https://stiffstream.com
Дата: 12.08.23 05:54
Оценка:
Здравствуйте, Кодт, Вы писали:

S>>Сразу видно человека, который server-side занимается


S>>И нет, Chrome, у которого регулярно падают вкладки, не есть хороший пример того, как падают процессы в графах с рестартами от супервизора.


К>Как человек, писавший яндекс-браузер (форк хрома), имею сказать!

К>Изоляция процессов — это как раз хороший подход. По нескольким причинам.

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

Но дорогой

Google или Яндекс может себе позволить увеличение стоимости. Какая-то условная контора "Рога и Ко" или молодой динамичный стартап с прижимистым владельцем
Автор: Pauel
Дата: 10.08.23
... Ну тут по разному, но чем меньше компания, тем меньше возможностей.

К>В-третьих, отказ от пользовательских исключений — это меньший размер кода, какие-то копеечки производительности (а для графического движка эти копеечки имеют критическое значение) и специфическая дисциплина программирования. Пропадает "теневая система типов".

К>На самом деле, объём писанины при этом вырастает не очень сильно. Потому что весь код, который должен не взирать на исключения, — он таковым и остаётся. Мест, где реально надо смотреть, обрабатывать и пробрасывать флажки ошибок, немного.

Как мне представляется, писать код можно в двух стилях:

— в нормальном, т.е. с обеспечением exception safety (т.е. RAII, откаты изменений при вылете исключений, контроль за тем, чтобы исключение не стрельнуло в noexcept контексте и т.д.). Такой код можно будет использовать и там, где исключения включены, и там, где throw превращается в немедленный std::terminate;
— в стиле fail kill-fast, т.е. в случае чего сразу резать не дожидаясь перитонита std::terminate.

Так вот, код, написанный во стиле kill-fast сложно переиспользовать между проектами. И, жирное ИМХО, стиль kill-fast не должен применяться при написании библиотек.
Re[6]: writing library | поддержка отказа от исключений
От: CreatorCray  
Дата: 12.08.23 06:45
Оценка:
Здравствуйте, so5team, Вы писали:

S>Открываешь Google Drive, затем открываешь один или два документа оттуда (они открываются в новых вкладках), оставляешь вкладку с Google Drive открытой, но в фоне, начинаешь работать с открытыми документами. С вероятностью больше 50% в течении часа-двух вкладка с Google Drive упадет.


Гы! Забавно что хром дохнет на своём же гуглодрайве.
У меня такого сценария не существует, я никогда не залогинен в браузере в гугле с десктопа. Всякое другое не падает.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[7]: writing library | поддержка отказа от исключений
От: so5team https://stiffstream.com
Дата: 12.08.23 08:32
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Гы! Забавно что хром дохнет на своём же гуглодрайве.

CC>У меня такого сценария не существует, я никогда не залогинен в браузере в гугле с десктопа. Всякое другое не падает.

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

Сейчас Chrome, вроде бы, вообще выгружает неактивные вкладки, при повторной активации происходит перезагрузка страницы. Таких падений стало заметно меньше.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.