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