Конструкторы, которые не являются noexcept, не должны вызываться до запуска программы
Конструкторы, которые не являются noexcept, не должны вызываться до запуска программы.
На C++ компилятор отвечает на исключение следующими шагами:
Компилятор пытается сопоставить исключение с обработчиком в текущих возможностях или более высоких возможностей.
Если исключение совпадает с обработчиком, обработчик принимает исключение и начинает размотку стека. Во время размотки стека Выполнение программы перемещается из возможностей, которая создает исключение, во внешние возможности в обратном порядке. Выполнение программы затем вызывает деструкторы для каждой переменной в стеке, которые еще не уничтожены. После размотки стека выполнение программы возобновляется из линии сразу после инициируемого обработчика.
Если исключение не совпадает с обработчиком, то компилятор завершает выполнение определенным реализацией способом. То есть точный процесс завершения программы зависит от конкретного набора программного и оборудования, которое вы используете. Например, компилятор может вызвать std::terminate(), который, в свою очередь, может вызвать std::abort() для ненормального прекращения выполнения. На основе реализации, стек может не быть размотан, прежде чем программа будет прервана. Если стек не размотан до завершения программы, то деструкторы переменных в стеке не вызываются, что приводит к утечке ресурсов и уязвимостям безопасности.
Перед запуском программы вызываются конструкторы статических или глобальных объектов, чтобы создать и инициализировать эти объекты. Если такой конструктор поднимает исключение, компилятор может ненормально прекратить выполнение кода, не разматывая стек. Рассмотрим этот код, где конструктор статического объекта obj может вызвать исключение.
class A{
A(){
//...
}
};
static A obj;
main(){
//...
}obj создается путем вызова A() перед main() запускается. Потому что A() вызывается перед запуском программы, обработчик исключений не может совпадать с исключениями, вызванными A(). Исходя из реализации, такое исключение может привести к прекращению работы программы без размотки стека, что приведет к утечке памяти и уязвимостям безопасности.Поскольку исключения, вызванные конструкторами статических или глобальных объектов, не могут быть сопоставлены с обработчиком исключений, объявите эти конструкторы как noexcept.
Polyspace® флаги, где non - noexcept непосредственно вызываются конструкторы статического или глобального объекта. В нем также подсвечиваются несовместимые конструкторы.
Если вы ожидаете нарушения правил, но не видите его, обратитесь к разделу «Стандартные нарушения кодирования не отображаются».
| Группа: Обработка исключений |
| Категория: Необходимый, Автоматизированный |