Not exception-safe default move constructors (demonstrated on std::pair)
Dmitry Marakasov
amdmi3@amdmi3.ru
Thu Feb 21 17:46:00 GMT 2013
Hi!
I'm not really sure which (g++ or libstdc++) problem this really is, so
posting into both lists.
The problem is described here:
http://cpp-next.com/archive/2009/10/exceptionally-moving/
- You have two classes:
A, which has a proper move constructor which doesn't throw
B, which which only has copy constructor which may throw
- You have an std::pair<A, B>
- You move a pair
std::pair<A, B> pair1;
try {
std::pair<A, B> pair2(std::move(a));
}
What happens:
- A part is moved with move constructor. This is obviously destructive
to pair1.
- B part is copied as it doesn't have move constuctor.
- Now, that copy constructor throws (which is pretty expectable is it
likely allocates resources). After this, as A part was already moved,
we're left with corrupted pair1 (with empty A part).
The same problem applies to most containers, but, for example, in
std::vector it is solved gracefully:
--- bits/vector.tcc from gcc-4.8:
pointer __tmp = _M_allocate_and_copy(__n,
_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_start),
_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_finish));
---
so move semantics are only used IF the type has non-throwing(noexcept)
move constructor.
However, with pair this does not apply:
--- bits/stl_pair.h from gcc-4.8:
struct pair {
...
constexpr pair(pair&&) = default;
---
Either the default constructor generated by gcc is unsafe, or there
should be custom, safe move constuctor with corresponding enable_if.
I lean towards the former, as safe default move constuctors should be
always generated probably, and specific ones may be really hard to
implement for more complex types (tuples).
I've written a small program which demonstrates the problem:
https://gist.github.com/AMDmi3/5005557
tested it on FreeBSD with gcc-4.8 and on Debian with gcc-4.7, and it
showed problem on both.
Is this really a gcc problem? Should I file a bug?
--
Dmitry Marakasov . 55B5 0596 FF1E 8D84 5F56 9510 D35A 80DD F9D2 F77D
amdmi3@amdmi3.ru ..: jabber: amdmi3@jabber.ru http://www.amdmi3.ru
More information about the Gcc-bugs
mailing list