Document number: N3166=10-0156
Date: 2010-10-13
David Svoboda
svoboda@cert.org

Destructors default to noexcept

During the Rapperswil meeting, WG21 discussed the prospect of having destructors with no explicit exception specification default to noexcept(true). This was proposed informally by national body comments FI 17 and GB 40. The committee seemed favorable to entertaining such a prospect.

Having destructors default to noexcept improves the overall security of a program. A destructor that throws an exception is likely to cause unexpected termination, but only during stack unwinding associated with another exception being thrown and caught. If such a destructor is noexcept, then the destructor's throw causes immediate program termination, whether or not it is being executed during exceptional stack unwinding. Thus this change serves to increase the abnormal termination rate of programs with throwing destructors (that also lack throw() or noexcept clauses). This will serve to call attention to these destructors, where they can be modified, either with a throws() or noexcept clause, or a redesign. This will result in clearer code that terminates less often.

The CERT C++ Secure Coding rule ERR33-CPP forbids destructors from throwing exceptions.

GB 60 and CH 16 have also requested that instances of throw() be replaced with noexcept in the library. This is being proposed by N3148.

This paper presents proposed wording for this set of changes.

Rationale

There is some controversy over the validity of destructors that throw exceptions. This paper tries to avoid the controversy by stipulating that while many people consider destructors that throw to be inherently bad code, some still believe that throwing destructors can still be useful. This paper does not forbid throwing destructors; it merely requires that they indicate their status using a throws() or noexcept clause. Therefore this paper tries to align the C++0x standard with the majority viewpoint while tolerating minority viewpoints.

Identified changes

All changes in this paper are against N3126.

Wording

12.4 Destructors

Add the following paragraph after paragraph 10:

If a destructor has no explicit exception-specification, it is treated as if it were specified with noexcept( true). That is, the destructor will not throw any exceptions.

15.4 Exception Specifications

Modify paragraph 12 thus:

A destructor with no explicit exception-specification is treated as if it were specified with noexcept( true). That is, the destructor does not throw any exceptions. Any otherA function with no exception-specification or with an exception-specification of the form noexcept( constant-expression ) where the constant-expression yields false allows all exceptions. An exception-specification is non-throwing if it is of the form throw(), noexcept, or noexcept(constant-expression ) where the constant- expression yields true. A function with a non-throwing exception-specification does not allow any exceptions.

References

CERT C++ Secure Coding Standard:
ERR33-CPP. Destructors must not throw exceptions
https://www.securecoding.cert.org/confluence/x/UgY

Becker, Pete, N3126=10-0116: Working Draft, Standard for Programming Language C++, 2010-08-21

Garcia, J. Daniel, N3148=10-0138: throw() becomes noexcept (Version 2), 2010-10-08