Strange behavior std :: is_nothrow_destructible

The following code runs static_assert , although I don't think it should:

 #include <type_traits> template< typename T > struct Tmp { ~Tmp() noexcept( std::is_nothrow_destructible< T >::value ) {} }; struct Foo; struct Bar { // Comment this out for the problem to go away Tmp< Foo > xx; // ..or this Bar() {} }; struct Foo {}; // This triggers static_assert( std::is_nothrow_destructible< Foo >::value, "That odd" ); int main() { } 

When compiling with:

 g++-4.9 -std=c++11 nothrow_destructible_bug.cc 

The following is done:

 nothrow_destructible_bug.cc:20:1: error: static assertion failed: That odd static_assert( std::is_nothrow_destructible< Foo >::value, "That odd" ); ^ 

Why noexcept just using Foo to create a template in an unrelated class cause it to lose noexcept status? I thought this was a compiler error, but I tried it with all the latest versions of both gcc and clang, and they all seem to give the same error.

+5
source share
1 answer

Where you use Tmp< Foo > xx , Foo is an incomplete type. This violates one of the prerequisites for using is_nothrow_destructible , and its use is undefined. One of the features of this UB for is_nothrow_destructible is false.

A note on using Tmp will avoid this problem. Since the template is not created before its use, commenting on the constructor will also avoid the problem, because the template has not yet been created.

Moving the struct Foo definition to Bar should also fix the problem.

+4
source

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


All Articles