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