Main Content

Uncaught exception

Exception propagates uncaught to the main or another entry-point function

Description

This check looks for the following issues:

  • An uncaught exception propagates to the main or another entry-point function.

  • An exception is thrown in the constructor of a global variable and not caught.

  • An exception is thrown in a destructor call or delete expression.

  • An exception is thrown before a previous throw expression is handled by a catch statement, for instance, when constructing a catch statement parameters.

  • A noexcept specification is violated. For instance, a function declared with noexcept(true) is not supposed to throw any exceptions but an exception is thrown in the function body.

In these situations, according to the C++ standard, the std::terminate function is called and can cause unexpected results.

Note that the Uncaught exception check on functions from the Standard Template Library is green, even though Polyspace stubs these functions and does not check if a function throws an exception.

Examples

expand all

#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);
}

In this example, the call to method initialVector::getValue throws an exception. This exception propagates uncaught to the main function resulting in a red Uncaught exception check.

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(); 
}

In this example:

  • The call to funcNegative throws an exception. However, the exception is placed inside a try block and is caught by the corresponding handler (catch clause). The Uncaught exception check on the main function appears green because the exception does not propagate to the main.

  • The call to funcPositive does not throw an exception in the try block. Therefore, the catch block following the try block appears gray.

class error {
};

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

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

In this example, the delete operator calls the destructor X::~X(). The destructor throws an exception that appears as a red error on the destructor body and dashed red on the delete operator. The exception does not propagate to the catch block. The code following the exception is not verified. This behavior enforces the requirement that a destructor must not throw an exception.

The black assert statement suggests that the exception has not propagated to the catch block.

#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());
}

In this example, the runningSum function throws an exception only if index is outside the range [0,SIZE]. Typically, an error that occurs due to instructions in an if statement is orange, not red. The error is orange because an alternate execution path that does not involve the if statement does not produce an error. Here, because the loop is infinite, there is no alternate execution path that goes outside the loop. The only way to go outside the loop is through the exception in the if statement. Therefore, the Uncaught exception error is red.

#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();                    
    }
}

In this example, an exception is rethrown in the function f() outside a catch block. A rethrow occurs when you call throw by itself without an exception argument. A rethrow is typically used inside a catch block to propagate an exception to an outer try-catch sequence. Polyspace® Code Prover™ does not support a rethrow outside a catch block and produces a red Uncaught exception error.

Check Information

Group: C++
Language: C++
Acronym: EXC