Исключения должны быть повышены только после запуска и перед завершением
Исключения должны быть повышены только после запуска и перед завершением.
На C++ процесс обработки исключений запускается во время выполнения main()
, где исключения, возникающие в различных осциллографах, обработаны обработчиками исключений в тех же или смежных осциллографах. Прежде, чем запустить выполнение main()
, компилятор находится в фазе запуска, и после окончания выполнения main()
, компилятор находится в фазе завершения. Во время этих двух фаз компилятор выполняет набор предопределенных операций, но не выполняет кода.
Если исключение повышено или во время фазы запуска или во время фазы завершения, вы не можете записать обработчик исключений, который компилятор может выполнить в тех фазах. Например, вы можете реализовать main()
как function-try-catch
блокируйтесь, чтобы обработать исключения. catch
блоки в main()
может обработать только исключения, повышенные в main()
. Ни один из catch
блоки могут обработать исключения, повышенные во время фазы запуска или завершения. Когда такие исключения повышены, компилятор может неправильно отключить выполнение кода, не раскручивая стек. Рассмотрите этот код где конструкция и разрушение статического объекта obj
может вызвать исключение.
class A{ A(){throw(0);} ~A(){throw(0)} }; static A obj; main(){ //... }
obj
создается путем вызова A()
перед main()
запускается, и это уничтожается путем вызова ~A()
после main()
концы. Когда A()
или ~A()
повышает исключение, обработчик исключений не может быть соответствующим им. На основе реализации такое исключение может привести к завершению программы без раскручивания стека, ведя к утечке памяти и уязвимостям системы обеспечения безопасности.Избегайте операций, которые могут повысить исключение в частях вашего кода, который может быть выполнен перед запуском или после завершения программы. Например, избегайте операций, которые могут повысить исключения в конструкторе и деструкторе статических или глобальных объектов.
Polyspace® отмечает глобальную переменную или объявление статической переменной, которое использует вызываемую сущность, которая может повысить исключение. Например:
Функция: Когда вы вызываете функцию инициализатора или конструктора непосредственно, чтобы инициализировать глобальную или статическую переменную, проверки Polyspace, повышает ли функция исключение и отмечает объявление переменной если функциональное повышение силы исключение. Polyspace выводит ли функциональное повышение силы исключение независимо от его спецификации исключения. Например, если noexcept
конструктор повышает исключение, Polyspace отмечает его. Если инициализатор или конструктор вызывают другую функцию, Polyspace принимает, что вызванная функция может повысить исключение, только если это задано как noexcept(<false>)
. Некоторые стандартные библиотечные функции, такие как конструктор std::string
, используйте указатели на функции, чтобы выполнить выделение памяти, которое может повысить исключения. Polyspace не отмечает объявление переменной, когда эти функции используются.
Внешняя функция: Когда вы вызываете внешние функции, чтобы инициализировать глобальную или статическую переменную, Polyspace отмечает объявление, если внешняя функция задана как noexcept(<false>)
.
Виртуальная функция: Когда вы вызываете виртуальную функцию, чтобы инициализировать глобальную или статическую переменную, Polyspace отмечает его, если виртуальная функция задана как noexcept(<false>)
в любом производном классе. Например, если вы используете виртуальную функцию инициализатора, которая объявляется как noexcept(<true>)
в базовом классе и noexcept(<false>)
в последующем производном классе Polyspace отмечает его.
Указатели на функцию: Когда вы используете указатель на функцию, чтобы инициализировать глобальную или статическую переменную, Polyspace принимает, что указатель на функцию не повышает исключения.
Polyspace игнорирует:
Исключения повышены в деструкторах
Исключения повышены в atexit()
операции
Polyspace также игнорирует динамический контекст при проверке на исключения. Например, вы можете инициализировать глобальную или статическую переменную при помощи функции, которая повышает исключения только в определенном динамическом контексте. Polyspace отмечает такое объявление, даже если исключение никогда не может повышаться. Можно выровнять по ширине такое нарушение при помощи комментариев в Polyspace.
Если вы ожидаете нарушение правила, но не видите его, обратитесь к Кодированию Стандартных Нарушений, Не Отображенных.
Группа: Обработка исключений |
Категория: необходимый, автоматизированный |