exponenta event banner

Непроверенное исключение

Исключение распространяется незаметно на main или другая функция точки входа

Описание

Эта проверка позволяет выявить следующие проблемы:

  • Непроверенное исключение распространяется на main или другую функцию точки входа.

  • Исключение создается в конструкторе глобальной переменной и не перехватывается.

  • Исключение возникает при вызове деструктора или delete выражение.

  • Создается исключение, прежде чем предыдущее выражение throw обрабатывается catch оператор, например, при построении catch параметры оператора.

  • A noexcept спецификация нарушена. Например, функция, объявленная с помощью noexcept(true) не должно вызывать никаких исключений, но исключение создается в теле функции.

В этих ситуациях, согласно стандарту C++, std::terminate вызывается функция, которая может привести к неожиданным результатам.

Обратите внимание, что проверка исключений Uncaught для функций из библиотеки стандартных шаблонов имеет зеленый цвет, несмотря на то, что Polyspace блокирует эти функции и не проверяет, вызывает ли функция исключение.

Примеры

развернуть все

#include <vector>
using namespace std;

class error {};

class initialVector {
private:
  int sizeVector;
  vector<int> table;
public:
  initialVector(int size) {
    sizeVector = size;
    table.resize(sizeVector);
    Initialize();
  }
  void Initialize();
  int getValue(int number) throw(error);
};

void initialVector::Initialize() {
  for(int i=0; i<table.size(); i++)
    table[i]=0;
}

int initialVector::getValue(int index) throw(error) {
  if(index >= 0 && index < sizeVector)
    return table[index];
  else throw error();
}

void main() {
    initialVector *vectorPtr = new initialVector(5);
    vectorPtr->getValue(5);
}

В этом примере вызов метода initialVector::getValue выбрасывает исключение. Это исключение распространяется незаметно на main функция, приводящая к красной проверке исключения Uncaught.

class error {
public:
  error() {  }
  error(const error&) { }
};


void funcNegative() {
  try {
    throw error() ;
  } catch (error NegativeError) {
  }
}

void funcPositive() {
  try {
  }
  catch (error PositiveError) {
  /* Gray code */
  }
}

int input();
void main()
{
    int val=input();
    if(val < 0)
        funcNegative(); 
    else
        funcPositive(); 
}

В этом примере:

  • Вызов funcNegative выбрасывает исключение. Однако исключение размещено внутри try блок и улавливается соответствующим обработчиком (catch пункт). Проверка исключения Uncaught на main функция отображается зеленым цветом, поскольку исключение не распространяется на main.

  • Вызов funcPositive не создает исключения в try блок. Следовательно, catch блок, следующий за try блок отображается серым цветом.

class error {
};

class X
{
public:
  X() {
    ;
  }
  ~X() {
    throw error();
  }
};

int main() {
  try {
    X * px = new X ;
    delete px;
  } catch (error) {
    assert(1) ;
  }
}

В этом примере delete оператор вызывает деструктор X::~X(). Деструктор создает исключение, которое отображается как красная ошибка на теле деструктора и пунктирно-красная на delete оператор. Исключение не распространяется на catch блок. Код, следующий за исключением, не проверен. Это поведение требует, чтобы деструктор не создавал исключения.

Черный assert оператор предполагает, что исключение не распространилось на catch блок.

#include<stdio.h>
#define SIZE 100

int arr[SIZE];
int getIndex();

int runningSum() {
  int index, sum=0;
  while(1) {
    index=getIndex();
    if(index < 0 || index >= SIZE)
      throw int(1);
    sum+=arr[index];
  }
}

void main() {
    printf("The sum of elements is: %d",runningSum());
}

В этом примере runningSum функция выдает исключение только в том случае, если index находится вне диапазона [0,SIZE]. Как правило, ошибка, возникающая из-за инструкций в if оператор оранжевый, а не красный. Ошибка оранжевого цвета, поскольку альтернативный путь выполнения не включает if инструкция не приводит к ошибке. Здесь, поскольку цикл бесконечен, нет альтернативного пути выполнения, который выходит за пределы цикла. Единственный способ выйти за пределы цикла - через исключение в if заявление. Поэтому ошибка исключения Uncaught имеет красный цвет.

#include <string>

void f() { throw; }        //rethrow not allowed - an error is raised here
void main() {
    try {
        throw std::string("hello");
     }
    catch (std::string& exc) {
        f();                    
    }
}

В этом примере в функции повторяется особая ситуация. f() за пределами catch блок. Повторный вызов происходит при вызове throw сама по себе без аргумента исключения. Перетекание обычно используется внутри catch блок для распространения исключения на внешний try-catch последовательность. Prover™ кода Polyspace ® не поддерживает возврат за пределы catch и создает красную ошибку исключения Uncaught.

Проверить информацию

Группа: C++
Язык: C++
Акроним: EXC