1

I am messing around with throwing move constructors and assignment operators.

It is a well known problem with std::vector that the vector elements have to be copied on reallocation, and cannot be moved, if the move constructor of said elements is not noexcept. This is to preserve the strong exception safety guarantee of the vector (if moving an element throws and we were in the middle of moving the entire vector, we'd be left with half a vector of moved elements, so it's better to copy so we can at least rollback if the operation fails).

However, what I did not know is that std::tuple suffers from this problem as well. Given a std::tuple<A, B, A>, where the move assignment operator of B throws, moving said tuple results in just the first A object being moved into the new tuple, while the latter two remain in the old tuple. We essentially get the object split in half. I just tested this exact scenario and, sure enough, the tuple is now in an inconsistent state.

I then tried the same thing with just a struct with those same three members, A, B and A again. I was horrified to find out that it has the exact same problem. The default move assignment operator does not take care of exception safety.

Is this actually the intended behavior? Does std::tuple not provide the strong exception safety guarantee? Does the default move assignment operator not provide said guarantee?

It seems like a massive issue. Do we have to explicitly provide the move constructor and move assignment operator for the cases in which the moving of members might throw? This essentially means always providing it in generic/template contexts. It is a lot of work. What can we do about it?

super
  • 278
  • 1
  • 11
  • 3
    Strong exception safety is not free. If I don't need it, why would I pay for it? – Evg Dec 19 '21 at 11:32
  • You would expect the move constructor to copy the elements? The case of `vector` is different because it's implementing "expanding" behavior with a strong exception guarantee that existed before move semantics existed. – Aykhan Hagverdili Dec 19 '21 at 11:39

0 Answers0