Недавно я попытался ответить, что я думал, будет simple question по спецификации исключения noexcept
. В результате я обнаружил, что мое фундаментальное понимание noexcept
было неправильным.гарантии noexcept и надежности
При чтении the current draft standard, чтобы исправить мое недоразумение, я обнаружил, что задаю несколько вопросов о noexcept
, на которые не ответил here.
- Должно ли
noexcept
считаться гарантией безопасности, что функция при вызове будет не только не бросать, но и не испортить состояние? - Предполагая, что (1.) неверно: правильно ли использовать
noexcept
в качестве переносного FailFast, чтобы прервать приложение без очистки, чтобы предотвратить повреждение сохраненного состояния?
Разъяснение к (2): Цель состоит в том, чтобы предотвратить только деструктор вызовов дальше вверх по стеку от noexcept
не предотвратить раскручивание внутри него. Это основано на предположении, что это идеальная среда RAII, а деструкторы в стеке могут вывести глобальное состояние в постоянство, таким образом развращая его.
Пример того, как раскручивание не сформованную:
#include <iostream>
#include <exception>
namespace{
struct foo{
void change_state() noexcept
{
// change state and fail
throw std::exception();
}
~foo(){
std::cout << "Destructor called, saved state corrupted!" <<std::endl;
}
};
}
int main(){
::std::set_terminate([](){
std::cout<< "Terminate called" <<std::endl;
});
foo f;
f.change_state();
return 0;
}
как я понимаю 'noexcept': даже если эта штука бросает, я не хочу об этом знать. Таким образом, это действительно не работает для «безопасности» или «правильности», оно работает, предотвращая исключение исключения из-за этого, поэтому ваша программа не заканчивается. – user2485710
Если исключение достигает самого внешнего блока функции, помеченной как «noexcept», вызывается 'std :: terminate'. Он не подавляет исключения вообще. Он обеспечивает барьер, по которому не могут быть исключены исключения – Mgetz
, о чем я писал ранее, о _runtime_, 'noexcept' работает во время компиляции, поэтому это подсказка для компилятора, компилятор оценивает ваши программы и, если есть вероятность, что что-то бросает , у вас есть возможность исправить это до _runtime_, потому что оператор 'noexcept' не будет работать в _compile time_. В некотором смысле он работает как «свойства типа», вы определяете свойство, которое должно быть оценено как «true», если компилятор не предупреждает вас, если тест проходит, вы знаете, что в _runtime_ у вас будут свои типы, определенные в вашем условия «признаков». То же самое для 'noexcept'. – user2485710