CppCoreGuidelines
CppCoreGuidelines copied to clipboard
New guideline request: Don't move from const
Do not use std::move on a const object.
As highligted in Meyers15: Move requests on const objects are silently transformed into copy operations.
That may be related to (or even be a note on) ES.56: Write std::move() only when you need to explicitly move an object to another scope
A note about it seems more than enough. I don't think a guideline for "don't do pointless things that don't work" is necessary.
Editors call: We don't make rules about things that compilers routinely warn about, but we just tried this and were surprised to discover that major compilers do not warn about it. So we agree we should say something.
Editors call: We think the correct fix is to extend the 5th Enforcement bullet as follows:
- Flag when std::move is applied to other than an rvalue reference to non-const
Also, the 3rd bullet could use some cleanup since it shouldn't allow moving from forwarding references, which is correctly banned in the 4th bullet.
Update: No major compiler warns on this even at high warning levels (tried MSVC, Clang, GCC, Intel). How about that. Good catch, thank you for the suggestion.
"Never write std::move() on a const object, it is silently transformed into a copy (see Item 23 in [Meyers15])"
This is not true. std::move only performs a cast to rvalue, so no copies are involved, at least at this point.
Mayers writes: "Move requests on const objects are silently transformed into copy operations." Well, yes... but only when no appropriate overload exists. Indeed if const rvalue is passed to a function with no appropriate overload (e.g. rvalue of const std::string to std::string's constructor) then a copy will be made.
Besides that point, there are legitimate use cases for obtaining rvalues of const objects, for example to move their mutable state (members declared with mutable keyword).
example: https://godbolt.org/z/81jxhe7dx
I do agree that in most cases this probably isn't what author meant, but I would argue that this should be a hint rather than a warning.
Maybe the line could be changed to something like:
"use std::move on const object only if there exists a const&& overload of the function you are passing the object to"?
Btw msvc warns about it.
Uses of const X&& are so vanishingly rare that I don't think it's worth caring about them in the guidelines.
That's not the point. This document is a source of C++ knowledge and if you include false information here it will spread. Compiler vendors for example create warnings based on this document and if one of them, lets say MSVC, were to implement it exactly as stated here then people will get warnings no matter if they provide const && overloads for their functions (guess how I got here) (page):
When called on a const object, std::move returns a copy of the object, which is likely not the developer's intent.
This statement is false and in the "See also" section there is only one source leading to this document.
It would completely suffice to replace it with what I wrote in the comment above or something along the lines i.e. warn when there is no exact overload because probably unintentional copy is being made.
@jwakely So maybe if const&& are so rare we should not say anything about them? Just an option... I think either not saying anything or going into too much detail would be better than the status quo.
Is there a chance to change the wording such that it permitts correct use? Microsoft changed their error description C26478, but (I suppose to be conforming to the these guidelines) they still issue a warning on correct code (example).
What exactly would a real world use case for a cast to const && via move look like?