Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Consequently you should take steps to prevent std::terminate() from being invoked for two reasons. First because it involves implementation-defined behavior. Second, if the stack is not unwound on your platform, than RAII is violated. That is, destructors are not called, allocated memory is not freed, opened files are not flushed and closed, etc.

Non-Compliant Code Example (main())

In this example, main() does several useful work but does not catch any exceptions. Consequently, any exceptions thrown will call std::terminate(), and might not destroy any objects owned by the program.

Code Block
bgColor#FFcccc
int main(int argc, char** argv) {
  Object object; // might not get destroyed if exception thrown
  // do useful work
  return 0;
}

Compliant Solution (main())

In this code example, all exceptions are caught, allowing normal termination, even in the face of unexpected errors.

Code Block
bgColor#ccccff
int main(int argc, char** argv) {
  Object object;
  bool error = false;

  try {
    // do useful work
  } catch (...) {
    error = true;
  }

  return error ? -1 : 0; // object gets destroyed here
}

Compliant Solution (main())

An alternative is to wrap all of main()'s functionality inside a try-catch block.

Code Block
bgColor#ccccff
int main(int argc, char** argv) {
  try {
    Object object;
    // do useful work
    return 0; // object gets destroyed here
  } catch (...) {
    throw;  
  }
}

Non-Compliant Code Example (throw() Declaration)

A function that declares exception specifications must include every exception that might be thrown during its invocation. If an exception is thrown that is not included in its specification, control automatically reverts to std::unexpected(), which does not return.

...

Code Block
bgColor#FFcccc
using namespace std;
class exception1 : public exception {};
class exception2 : public exception {};

void f(void) throw( exception1) {
  // ...
  throw (exception2());
}

int main() {
  try {
    f();
    return 0;
  } catch (...) {
    cerr << "F called" << endl;
  }
  return -1;
}

Compliant Solution (throw() Declaration)

The following code example declares the same exception it actually throws

Code Block
bgColor#ccccff
using namespace std;
class exception1 : public exception {};
class exception2 : public exception {};

void f(void) throw( exception1) {
  // ...
  throw (exception1());
}

int main() {
  try {
    f();
    return 0;
  } catch (...) {
    cerr << "F called" << endl;
  }
  return -1;
}

Risk Assessment

Failing to handle exceptions can lead to resources not being freed, closed, etc.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

ERR12-C

1 (low)

1 (unlikely)

1 (low)

P1

L3

References

Wiki Markup
\[[ISO/IEC 14882-2003|AA. C++ References#ISO/IEC 14882-2003]\]
\[[MISRA 08|AA. C++ References#MISRA 08]\] Rule 15-3-2

...