Question

namespace QuantLib {

    //! Base error class
    class Error : public std::exception {
      public:
        /*! The explicit use of this constructor is not advised.
            Use the QL_FAIL macro instead.
        */
        Error(const std::string& file,
              long line,
              const std::string& functionName,
              const std::string& message = "");
        /*! the automatically generated destructor would
            not have the throw specifier.
        */
        ~Error() throw() {}
        //! returns the error message.
        const char* what() const throw ();
      private:
        boost::shared_ptr<std::string> message_;
    };

}

As you see through the comment, the destructor of class Error explicitly provides an empty implementation with no-throw specifier.

Question: Is this necessary? Or is this a good practice comparing to let the compiler generate a implicit destructor?

Was it helpful?

Solution

In C++11, destructors are implicitly throw() (unless any member or base of the type has a destructor with a different exception specification) so if you are compiling in C++11 mode there is no need.

If you are in C++03, you might want to add it, but whether it will have an effect or not is very implementation defined... Now, for documentation purposes you might want to add it, but again, it is commonly assumed that destructors don't throw.

OTHER TIPS

Destructors should always be designed to never throw exceptions. So in that sense, there's little point in declaring an empty destructor merely in order to mark it as no-throw.

Depends what you think throw() means.

What it actually means according to the standard is, "put extra code around every call to this function if necessary, or in the function itself, to ensure that if this function throws then the exception is caught and std::unexpected is called".

Certain compilers implemented it to mean "optimize calls to this function on the assumption that they will not throw", but (in violation of the standard) didn't implement the runtime check.

So, adding it to a destructor (which certainly shouldn't throw) out to (but in practice might not) add a runtime check that should never be triggered and therefore might help debug your code. It may or may not enable an optimization.

Destructors always implicitly have exception specifications:

[class.dtor] 12.4 p3

A declaration of a destructor that does not have an exception-specification is implicitly considered to have the same exception-specification as an implicit declaration (15.4).

[except.spec] 15.4 p14

An implicitly declared special member function (Clause 12) shall have an exception-specification. If f is an implicitly declared default constructor, copy constructor, move constructor, destructor, copy assignment operator, or move assignment operator, its implicit exception-specification specifies the type-id T if and only if T is allowed by the exception-specification of a function directly invoked by f’s implicit definition; f shall allow all exceptions if any function it directly invokes allows all exceptions, and f shall allow no exceptions if every function it directly invokes allows no exceptions.

So, no, it's not necessary for you to use an exception specification.


In C++03 user defined destructors did not have an implicit exception specification, so if you do define your own destructor you can't rely on the compiler to automatically add the appropriate exception specification. But implicitly declared destructors have the same implicit exception specification as in C++11.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top