I always thought that when an object is moved it is left in “partially formed” state ; you can only delete or reassign it. I read in Nicolai Josuttis "C++ Move Semantics” book that in the STL (and generally) a move operation must be implemented in order to let the object in “valid but unspecified” state. Meaning that the invariants must be maintained.
It is reported also in Herb Sutter blog below.
Is JUCE conforms to the STL requirements?
Is people here conforms to the STL requirements?
(I think that keeping the invariants in unbroken state ruins the benefit of moving.)
According to blog above, in the STL you are allowed to use (a subset of the methods from) something that has been moved-from… (and it is required to implement move like this).
Sure, but I’d much rather have a tool that can give me a build error to address rather than trying to remember when you can or can’t use something that’s been moved-from. Even if the tool sometimes gives false-positives, it’s still the most reliable way to ensure working software.
Interesting, indeed. The whole PDF reads more like a rant: the author complains that user-defined classes break after std::move and argues that the C++ standard should somehow (semantically?) guarantee that even such class designs remain fully valid. But in reality, the standard only requires that moved-from objects are valid but unspecified — preserving user-defined invariants is the responsibility of the class designer, not the language.
I don’t quite get what’s the issue here? If you successfully(*) move an object, you should consider it unusable after that anyway. IMHO, it’s just tiresome language lawyering what the exact state of the object will be after a move.
Have you encountered some practical issue with some Juce class or classes because of this?
(*) By successful, I mean the object internals were actually moved into another object and not just copied.
I think this is the misconception that’s being pointed out in these blogs - “moving” an object in C++ doesn’t necesserily mean its data members are altered in any way. There are cases where a “moved-from” object would be left in an invalid state, but also cases where a “moved-from” object is left exactly as it was.
I agree with this though, and is why I like to use the linters I mentioned about to catch these things. Moving is more of a note to the reader to say “I’m done with this thing so I’m handing over to some other object”.
I think also that a moved-from object should not be used anymore (except for destruction or assignment). But AFAIK, Sutter, Hinnant, and Josuttis (people with large audience) teach that a moved-from object should be usable for methods with no preconditions (and not only into the STL). Thus, users of your library (and coworkers) should be aware of your assumptions to avoid bad surprises. That was the motivation of the original question. Which move semantics is adopted by JUCE classes?
I think in many cases the object would still be in a valid but unspecified state, and I would expect destruction and assignment to always work. However, I wouldn’t feel comfortable making a blanket statement. If we noticed we were leaving an object in some kind of invalid state following a move, I can imagine it would spark discussion in the MR. If we agreed, that in this instance, it was the best/right thing to do, we might add jasserts to help catch misuse. Although I can’t think of case where this has actually happened.