Should we provide a destructor without specifying a specification?

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 can see from the comment, the Error class destructor explicitly provides an empty implementation without a no-throw specifier.

Question : Is this necessary? Or is it good practice to have the compiler generate an implicit destructor?

+6
source share
4 answers

In C ++ 11, destructors implicitly throw() (unless any member or base of 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 can add it, but whether it will have an effect or not, this is a very specific implementation ... Now for documentation purposes you can add it, but again, it is usually believed that destructors do not throw .

+8
source

Destructors should always be designed to never throw exceptions . Thus, in this sense, it makes little sense to declare an empty destructor just to mark it as a non-throw.

+5
source

Depends on what you think throw() .

What the standard actually means is that “add additional code around each call to this function, if necessary, or in the function itself, to ensure that if this function is selected, an exception will be caught and called std::unexpected ".

Some compilers have implemented this to mean “optimizing calls to this function under the assumption that they will not throw”, but (in violation of the standard) did not perform runtime checks.

So, adding it to the destructor (which, of course, should not be thrown) on (but in practice cannot) add a run-time check that should never run and, therefore, can help debug your code. It may or may not include optimization.

+4
source

Destructors always implicitly have exception specifications:

[class.dtor] 12.4 p3

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

[except.spec] 15.4 p14

An implicitly declared special member function (clause 12) must have an exception specification. If f is an implicit declared default constructor, copy constructor, move constructor, destructor, copy assignment operator, or move assignment operator, its implicit exception specification indicates the identifier type of T if and only if T is allowed by the exception specification of a function directly called by fs implicitly definition; f allows all exceptions if any function that it calls directly allows all exceptions, and f does not allow exceptions if every function it calls does not allow exceptions.

So no, you do not need to use the exception specification.


In C ++ 03, user-defined destructors did not specify an implicit exception specification, so if you define your own destructor, you cannot 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.

+3
source

Source: https://habr.com/ru/post/916679/


All Articles