rspec/rules/S6352/cfamily/rule.adoc
Fred Tingaud 16f6c0aecf
Inline adoc when include has no additional value (#1940)
Inline adoc files when they are included exactly once.

Also fix language tags because this inlining gives us better information
on what language the code is written in.
2023-05-25 14:18:12 +02:00

56 lines
2.0 KiB
Plaintext

== Why is this an issue?
`std::move` is not really moving anything, but tells the compiler that a value can be considered as no longer useful. It is technically a cast to a RValue, and allows overload resolution to select the version of a function that will perform destructive operations on that value (therefore actually moving from it).
----
void f(A const &a); // Just reading from a
void f(A&& a); // I can perform destructive operations on a, like resource stealing
void g() {
A a;
f(a); // First overload is selected
f(std::move(a)); // Second overload is selected
}
----
As a consequence, calling `std::move` on an object and then not directly using the returned value as a function argument is not the typical pattern, and may be indicative of a bug. Note that calling a member function on the result of `std::move` _is_ considered as passing it to a function (as the hidden `this` parameter), as well as using it as an operand (the called function is the overloaded operator) or initializing an object with it (the called function is the constructor).
=== Noncompliant code example
[source,cpp]
----
void sink(A &&a) {
std::move(a); // Noncompliant, and not doing anything
}
void f(A &&a) {
// May or may not move the member name, depending on its type, the intent is not clear anyways,
// for instance, is `a` supposed to be in a moved-from state after the call?
g(std::move(a).name); // Noncompliant
}
----
=== Compliant solution
[source,cpp]
----
void f(A &&a) {
g(std::move(a.name)); // Compliant, `a.name` is in moved-from state, `a` itself is not
----
=== Exceptions
Even if calling a built-in operator or initializing data of built-in type are not function calls, for consistency with cases that involve user-defined types, this rule will not report in those cases:
[source,cpp]
----
struct Data {A a; int b; };
Data add(Data &&d1, Data &&d2) {
return Data{
std::move(d1.a) + std::move(d2.a), // Compliant, operator+ might have an overload for A&&
std::move(d1.b) + std::move(d2.b) // Compliant by exception
};
}
----