cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

закрыть дыру в механизме исключений #378

Open apolukhin opened 3 years ago

apolukhin commented 3 years ago

Перенос предложения: голоса +4, -0 Автор идеи: crusader

По стандарту "throw XYZ" выделяет память под объект исключения "in unspecified way". Как следствие если это попытка аллокации проваливается -- поведение программы тоже "unspecified" и попытки обрабатывать нехватку памяти используя std:bad_alloc бессмысленны, ибо нет гарантии что само "throw std::bad_alloc()" в состоянии произойти.

Детали тут https://stackoverflow.com/questions/45497684/what-happens-if-throw-fails-to-allocate-memory-for-exception-object/45552806. Соответствующее предложение см. https://wg21.link/P0770R0.

Идея состоит в том чтобы ввести новое (эфемеральное) исключение, готорое гарантировано бросается независимо от состояния кучи. В контексте C++ Itanium ABI (используемого CLang/GCC/etc) это значит что если __cxa_allocate_exception() вернет NULL, то (вместо вызова std::terminate()) он будет передан в функции которые раскручивают стек и будет третироваться как специальный объект.

Как вариант (и для упрощения кода) эфемеральным исключением может быть std::bad_alloc -- чтобы он ловился через catch(std::bad_alloc). Понадобится способ отличения эфемерального std::bad_alloc от обычного ("bool std::is_ephemeral(std::bad_alloc&)" ?).

В контексте программы это значит что (в случае Itanium ABI) при нехватке памяти "throw MyException()" вместо аварийного завершения бросит эфемеральный std::bad_alloc, который может быть обработан и т.п. К сожалению, это также означает, что "throw 42" может также бросить эфемеральное исключение -- что может быть сюрпризом для пользователя (хотя это конечно лучше чем крэш или зависание, которое может случиться сейчас).

Я осознал, что у меня нет желания бороться с бюрократией комитета чтобы протолкнуть эту идею и закрыть эту дыру. Может у вас оно есть :-)

apolukhin commented 3 years ago

Айдар Фаттахов, 2 февраля 2019, 14:41 Почему это не проблема компиляторов?

yndx-antoshkka, 22 июля 2020, 12:05 Это скорее проблема ABI

Попробуйте зарепортить её сюда https://github.com/itanium-cxx-abi/cxx-abi