<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Hi,<div><br></div><div>There's one small piece of the noexcept specification left to implement. It's not only scary, it's also fiendishly difficult to find, being the only part of noexcept that isn't within [except]. [class.dtor]p3 says:</div><div><br></div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">"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."</span></font></div></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">This means that destructors suddenly grow exception specifications, and they may be really, really wrong. Consider this little class, which could be used as an RAII guard.</span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">class TransactionGuard {</span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">  DatabaseConnection& m_conn;</span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">public:</span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">  TransactionGuard(DatabaseConnection& conn) : m_conn(conn) {}</span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">  ~TransactionGuard() {</span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">    if (std::unhandled_exception()) { // if we're being destructed due to an exception being thrown</span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">      try { conn.rollback(); } catch(...) {} // rollback and swallow any errors, or we terminate</span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">    } else {</span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">      conn.commit(); // otherwise commit, and let exceptions escape</span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">    }</span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">  }</span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">};</span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">The above destructor would suddenly grow an exception-specification. Specifically, because it has no object data members, the exception-specification would be empty: it would be noexcept(true). If the conn.commit() call throws, the program would immediately terminate instead of letting the exception escape.</span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">Scary? Hell, yes! Useful? That too, when you consider that most constructors don't throw.</span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">Now, the rationale for this part of the standard was that throwing destructors are high-risk parts of a program, so programmers would know where they are and check them when upgrading to C++0x. This argument makes sense - if you consider the C++0x transition global and instantaneous. But in reality, with compilers adopting different parts of the standard in different order, it's a headache.</span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">So my question is, how should we implement this in Clang? Simply put it under C++0x? Have it enabled in C++0x by default, but add a switch to turn it off? Add an explicit switch to turn it on?</span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;"><br></span></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Helvetica; "><font class="Apple-style-span" size="3"><span class="Apple-style-span" style="font-size: 12px;">Sebastian</span></font></div></body></html>