3

Take the following code snippet:

#include <type_traits>

struct X { virtual ~X(); };

static_assert(std::is_nothrow_default_constructible<X>::value, "fail");

Under clang svn, it compiles fine. However, with gcc 4.7.2, the assertion fails. Which one is correct? (And if gcc is right, why?)

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
DirtY iCE
  • 431
  • 2
  • 12

1 Answers1

3

clang is correct.

There's been some wrangling on this, but the construction of an object causes its destructor to be potentially invoked:

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1424

So std::is_nothrow_default_constructible<X> is not only testing the default constructor, but also ~X().

By default ~X() has an implicit noexcept applied to it. If your example either made ~X() private or deleted it, or put a noexcept(false) on it, then the static_assert would fail.

I suspect that gcc 4.7.2 has not yet implemented the rule that destructors are implicitly noexcept.

Update

I made a sweep of CWG/LWG issues while answering the above, but missed the obvious one:

http://cplusplus.github.com/LWG/lwg-active.html#2116

Thanks much to Cassio Neri for pointing this out below. Mea culpa for not picking this up myself. I would delete this answer except that I think the information it contains is perhaps helpful. Thank you Cassio Neri.

Howard Hinnant
  • 206,506
  • 52
  • 449
  • 577
  • Great. Writing `noexcept` after destructor declaration fixes the problem for the time being. – DirtY iCE Feb 23 '13 at 21:19
  • 4
    @Howard: I might be missing something but whether std::is_nothrow_default_constructible must consider the destructor or not is an open issue: http://cplusplus.github.com/LWG/lwg-active.html#2116. You certainly understand how the LWG works much better than me so, please, correct me if my interpretation is wrong. (Thanks in advance.) Anyway, this bug has been reported to GCC: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 but (it seems to me) it's on hold waiting for clarification on the definition of std::is_nothrow_default_constructible. – Cassio Neri Feb 23 '13 at 23:53