小太郎
小太郎

Reputation: 5620

std::string not nothrow move assignable or comparable?

I was playing around with type_traits, and I discovered this strange property of std::string:

$ cat a.cpp
#include <string>
#include <type_traits>

static_assert(std::is_nothrow_move_assignable<std::string>::value, "???");
static_assert(noexcept(std::declval<std::string>() == std::declval<std::string>()), "???");
$ g++ -std=c++14 a.cpp
a.cpp:4:1: error: static assertion failed: ???
 static_assert(std::is_nothrow_move_assignable<std::string>::value, "???");
 ^
a.cpp:5:1: error: static assertion failed: ???
 static_assert(noexcept(std::declval<std::string>() == std::declval<std::string>()), "???");
 ^
$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609

Yet cppreference claims the move assignment operator and comparison operators are marked noexcept.

Am I doing something wrong? Is this a bug?

Upvotes: 5

Views: 641

Answers (1)

Jonathan Wakely
Jonathan Wakely

Reputation: 171403

Yet cppreference claims the move assignment operator and comparison operators are marked noexcept.

There was a defect report about this, because C++11 said the move assignment was noexcept but that was impossible to satisfy in general (because it might need to reallocate if moving from a string with an incompatible allocator that doesn't propagate). See DR 2063.

The standard has been fixed so that the exception specification depends on the properties of the allocator, and but until that new rule was implemented in GCC we did not make the operations noexcept. I implemented the fixed rules for GCC 6.1 (see PR 58265) and backported the change to the gcc-5-branch, but there hasn't been another release of GCC 5.x since then. It will be fixed in the 5.5 release, whenever that happens.

Upvotes: 4

Related Questions