Страницы

Поиск по вопросам

воскресенье, 29 декабря 2019 г.

Как работает noexcept в c++?

#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/

Комментариев нет:

Отправить комментарий