Move constructors and the Strong Exception Guarantee
Asked Answered
S

1

17

Just a quick question, on which I cannot find a good reference, especially with regard to current implementations of the future C++0x standard.

Since move constructors can throw, it means that some standard library functions cannot provide the strong exception guarantee (eg. vector<T>::resize()).

There was a proposal to 1) make all standard library move constructors "no throw", and 2) to add compile time checks on user code to ensure that eg. std::pair<std::string, MyType> defines a nothrow move constructor or no move constructor at all.

What happened to this proposal (esp. with respect to this question) ? How is the issue "solved" in the final draft ?

Most importantly, what does it imply for me when I use a recent GCC or MSVC 10 ? Does those implementations of the standard library provide the Strong Exception Guarantee on eg. std::vector<MyTypeWithAThrowingMoveConstructor>::resize() ?

EDIT: I didn't see this question which is clearly related. If there is a consensus on the fact that my question is a duplicate, then close it. However, I am really interested on what is implemented, not what has been discussed.

Selfabsorbed answered 15/5, 2011 at 21:37 Comment(4)
+1 pretty inquisitive questionFarber
Did they ever provide a strong exception guarantee? I mean, your copy constructor could always throw, so...Compositor
@Xeo: yes they did. It is easy to rollback a resize operation since the old buffer gets destroyed after all the copies have been successful. With a nothrow move constructor you can rollback too by moving elements back to the old buffer. With throwing move constructors, Bad Things can happen. Here we clearly see that there is a lack of a strong noexcept keyword.Selfabsorbed
@Xeo: Its easy to provide the strong exception guarantee on copy. If any copies fail then you revert back to the original (which has not changed). The problem with move is that you have modified the original. So while moving a container and you throw on the third element you can not guarantee that the first two elements can be reverted back to their original state.Santee
H
5

I haven't checked the specific implementations, but the general idea is that if the move constructor can throw, the vector will have to copy the elements instead. That way it is possible to roll back in case of an exception.

There is even a helper function move_if_noexcept defined in <utility> to help it decide what to do.

Henderson answered 15/5, 2011 at 21:53 Comment(2)
Interesting. I'm going to check whether this move_if_noexcept (btw you have a typo) helper is present on the libraries I am interested in.Selfabsorbed
@Alexander - MSVC10 doesn't have a chance to be fully conformant as the rvalue rules were changed after its release.Henderson

© 2022 - 2024 — McMap. All rights reserved.