rspec/rules/S5415/cfamily/rule.adoc

74 lines
2.0 KiB
Plaintext
Raw Normal View History

2021-04-28 16:49:39 +02:00
Calling ``++std::move++`` on objects that cannot be moved is suspicious and might hide nasty performance bug.
This can happen when calling ``++std::move++`` with const argument or with non-movable types.
This can also happen when passing the result of ``++std::move++`` as a const reference argument.  In this case, no object will be moved since the result is in a context where calling the move constructor is not possible. It makes sense to call ``++std::move++`` on a function argument when:
* The result of ``++std::move++`` is passed as an r-value reference.
* The result of ``++std::move++`` is passed by copy.
2021-04-28 16:49:39 +02:00
== Noncompliant Code Example
----
struct NonMovable{
NonMovable() = default;
NonMovable(NonMovable&) = default;
};
void f(NonMovable s);
void f(std::string s);
void g(const std::string &s);
void test() {
std::string s="****";
f(std::move(s));
g(std::move(s)); // Noncompliant: s is cast back to const l-value reference. s will not be moved.
const std::string constS="***";
f(std::move(constS)); // Noncompliant: constS will not be moved.
NonMovable t;
f(std::move(t)); // Noncompliant: std::move is useless on non-movable objects like t. Copy constructor is called.
}
----
2021-04-28 16:49:39 +02:00
== Compliant Solution
----
struct Movable{
Movable() = default;
Movable(Movable&) = default;
Movable(Movable&&) = default;
};
void f(Movable);
void f(std::string s);
void g(const std::string &s);
void test() {
std::string s="****";
f(std::move(s)); // Compliant: move constructor is called.
g(s); // Compliant: no misleading std::move is used.
Movables t;
f(std::move(t)); // Compliant: move constructor is called.
}
----
2021-04-28 16:49:39 +02:00
== See
* https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es56-write-stdmove-only-when-you-need-to-explicitly-move-an-object-to-another-scope[{cpp} Core Guidelines ES.56] - Write "std::move()" only when you need to explicitly move an object to another scope
ifdef::rspecator-view[]
== Comments And Links
(visible only on this page)
include::comments-and-links.adoc[]
endif::rspecator-view[]