Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::string not nothrow move assignable or comparable?

Tags:

c++

typetraits

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?

like image 741
小太郎 Avatar asked Sep 14 '16 14:09

小太郎


1 Answers

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.

like image 84
Jonathan Wakely Avatar answered Nov 03 '22 10:11

Jonathan Wakely