Uploaded image for project: 'Rules Repository'
  1. Rules Repository
  2. RSPEC-3743

Exceptions should not be thrown in "noexcept" functions

    XMLWordPrintable

    Details

    • Message:
      Hide
      * Remove this "throw" clause or "noexcept" on the function declaration.
      * Remove this "throw" clause or "throw()" on the function declaration.
      Show
      * Remove this "throw" clause or "noexcept" on the function declaration. * Remove this "throw" clause or "throw()" on the function declaration.
    • Highlighting:
      Hide

      throw clause

      Show
      throw clause
    • Default Severity:
      Critical
    • Impact:
      High
    • Likelihood:
      Low
    • Default Quality Profiles:
      Sonar way, MISRA C++ 2008 recommended
    • Covered Languages:
      C++
    • Remediation Function:
      Constant/Issue
    • Constant Cost:
      20min
    • Analysis Scope:
      Main Sources, Test Sources

      Description

      noexcept is a specifier that can be applied to a function declaration to state whether or not this function might throw an exception.

      This specifier is a crucial information for the compiler as it enables it to perform automatic optimizations. It is also used by the noexcept operator, so that a developer can know whether an expression can throw, and adapt the code accordingly (for instance, to decide to move or copy an object).

      When a function is specified noexcept, the compiler does not generate any code to throw exceptions and any uncaught exception will result in a call to std::terminate. This means that writing a noexcept function is an implicit agreement to the statement : "my program will terminate if any exception is thrown inside this function".

      It is a very strong commitment as there are so many ways to get an exception including any dynamic allocation.

      This rule raises an issue when an exception is thrown, directly or indirectly, from a function declared noexcept.

      Noncompliant Code Example

      #include <exception>
      #include <memory>
      
      using namespace std;
      
      class SafetyException {};
      class Engine {};
      unique_ptr<Engine> engine;
      
      bool safety_check() noexcept;
      void other_checks();
      
      void critical_checks() {
        if (!safety_check()) {
          throw SafetyException{};
        }
      }
      
      void do_checks() {
        critical_checks(); // can throw
        other_checks(); // can throw
      }
      
      void init() noexcept(true) { // noncompliant because...
        do_checks(); // can throw
        engine = std::make_unique<Engine>(); // can throw
      }
      

      Compliant Solution

      #include <exception>
      #include <memory>
      
      using namespace std;
      
      class SafetyException {};
      class Engine {};
      unique_ptr<Engine> engine;
      
      bool safety_check();
      void other_checks();
      
      void critical_checks() {
        if (!safety_check()) {
          throw SafetyException{};
        }
      }
      
      void do_checks() {
        critical_checks();
        other_checks();
      }
      
      void init() noexcept(true) { // compliant because ...
        try {
          do_checks(); // exception caught
          engine = std::make_unique<Engine>(); // exception caught
        } catch(std::exception e) {
          std::terminate();
        }
      }
      

      Exceptions

      Destructors are not handled by this rule because there is a specific rule about exceptions in destructors (see ExceptionInDestructor).

      See

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              loic.joly Loïc Joly
              Reporter:
              alban.auzeill Alban Auzeill
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Dates

                Created:
                Updated: