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

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

Описание

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

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

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

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

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

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

  • Тип данных исключения, которое на самом деле выдается, не находится в списке типов исключительной ситуации, которые функция, как объявляют, выдает.

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

Примечание

Uncaught exception начинает работу, функции от Стандартной библиотеки шаблонов, такие как operator new является зеленым, даже при том, что Polyspace блокирует эти функции и не проверяет, выдает ли функция исключение. Чтобы предотвратить блокирование, используйте опцию No STL stubs (-no-stl-stubs).

Примеры

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

#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 exception.

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)
        /* Green check */
        funcNegative(); 
    else
        /* Green check */
        funcPositive(); 
}

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

  • Вызов funcNegative выдает исключение. Однако исключение помещается в блоке try и отловлено соответствующим обработчиком (пункт catch). Uncaught exception начинает работу, функция 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 exception является красной.

#include <string>
using namespace std;

class negativeBalance {
public:
  negativeBalance(const string & s): errorMessage(s) {}
  ~negativeBalance() {}
private:
    string errorMessage;
};

class Account {
public:
  Account(long initVal):balance(initVal) {}
  ~Account() {}
  void debitAccount(long debitAmount) throw (int, char);
private:
  long balance;
};

void Account::debitAccount(long debitAmount) throw (int, char) {
    if((balance - debitAmount) < 0 )
        throw negativeBalance("Negative balance");
    else
        balance -= debitAmount;
}

void main() {
    Account *myAccount = new Account(1000);
    try {
        myAccount->debitAccount(2000);
    }
    catch(negativeBalance &) {
    }
    delete myAccount;
}

В этом примере типами, сопоставленными с оператором throw в методе Account::debitAccount, является int и char. Однако метод выдает исключение с типом negativeBalance. Поэтому проверка Uncaught exception производит красную ошибку на throw.

#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 последовательность. Polyspace® Code Prover™ не поддерживает перебросок вне блока catch и производит красную ошибку Uncaught exception.

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

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