#cpp #исключения #cpp11
Что делает спецификация noexcept? Я думал, что она не позволит функции кинуть исключение, но это не так, функция: int Foo() noexcept { throw std::runtime_error("error"); return 0; } компилируется, её вызов спокойно падает, значит исключение вылетело. noexcept ничего не изменил.
Ответы
Ответ 1
Спецификатор noexcept дает гарантию времени компиляции, что из функции не будет выброшено исключение. Однако такая гарантия достигается эквивалентно оборачиванию тела функции в блок try...catch с вызовом ::std::terminate: int Foo() noexcept { try { throw std::runtime_error("error"); } catch(...) { ::std::terminate(); } } Определить, что в теле функции исключений действительно не выбрасывается и соптимизировать их перехват компиляторы могут только в самых простых случаях. Идея была в том, что оптимизацию сможет осуществить вызывающий код. Но на практике это все не работает и контроля над исключениями во время компиляции, особенно после выкидывания спецификаторов исключений, в с++ фактически нет.Ответ 2
Этим вы как автор гарантируете, что ваша функция не генерирует исключений, так что компилятор может, полагаясь на это, выполнять ряд оптимизаций. Понятно, что вы хозяин своему слову - сам дал, сам и назад забрал! Только потом не удивляйтесь результатам - завершению программы. См., например, эту статейку.Ответ 3
В С++ 11 безусловный модификатор noexcept применяется к функциям, которые гарантированно не могут генерировать исключения. Должна ли функция быть объявлена таким образом - вопрос проектирования интерфейса. Отсутствие объявления функции как noexcept, когда вы точно знаете, что она не в состоянии генерировать исключения, - не более чем просто плохая спецификация интерфейса. Но есть и дополнительный стимул для применения noexcept к функциям, которые не генерируют исключений: это позволяет компиляторам генерировать лучший объектный код. В случае функции, объявленной как noexcept, оптимизаторам не надо ни поддерживать стек в сворачиваемом состоянии, ни гарантировать, что объекты в такой функции будут уничтожены в порядке, обратном созданию, если вдруг такую функцию покинет исключение. Этого одного достаточно для того, чтобы объявлять функции, о которых точно известно,что они не генерируют исключений, как noexcept . Литература из которой взят текст выше: https://www.ozon.ru/context/detail/id/34747131/
Комментариев нет:
Отправить комментарий