Исключения должны быть высказаны только после запуска и до окончания
Исключения должны быть сделаны только после пуска и до окончания работ.
В C++ процесс обработки исключений запускается во время выполнения main()
, где исключения, возникающие в различных возможностях, обрабатываются обработчиками исключений в тех же или смежных возможностях. Перед началом выполнения main()
компилятор находится в фазе запуска и после завершения выполнения main()
компилятор находится в фазе завершения. В течение этих двух фаз компилятор выполняет набор предопределенных операций, но не выполняет никакого кода.
Если исключение возникает во время фазы запуска или фазы завершения, вы не можете записать обработчик исключения, который может выполняться компилятором в этих фазах. Например, можно реализовать main()
как function-try-catch
блок для обработки исключений. The 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 определяет, может ли функция вызвать исключение независимо от спецификации исключения. Для образца, если a 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.
Если вы ожидаете нарушения правил, но не видите его, обратитесь к разделу «Стандартные нарушения кодирования не отображаются».
Группа: Обработка исключений |
Категория: Необходимый, Автоматизированный |