== Why is this an issue?

``++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

[source,cpp]
----
#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

[source,cpp]
----
#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).

ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

=== Message

* Remove this "throw" clause or "noexcept" on the function declaration.
* Remove this "throw" clause or "throw()" on the function declaration.


=== Highlighting

``++throw++`` clause


'''
== Comments And Links
(visible only on this page)

=== on 6 Nov 2019, 23:13:47 Loïc Joly wrote:
* One or 2 rules : Is ``++new++`` considered as a throwing operation from which we expect to be able to recover
* Should the rule be deactivated on ``++-fno-exception++`` ?
* It would be interesting to tell the user what exception can be thrown
*

endif::env-github,rspecator-view[]
