Consider the following mwe, implementing a simple class that overloads the multiply operator:
#include <iostream>
using namespace std;
class A {
public:
double a;
A &operator*(double b)
{
a *= b;
return *this;
}
friend A &operator*(double b, A &m) { return m * b; } // (*)
};
int main()
{
A a;
a.a = 5.0;
a * 3.0;
std::cout << a.a << std::endl;
3.0 * a;
std::cout << a.a << std::endl;
return 0;
}
It compiles and runs just fine, printing the expected output. However cppcheck gives the following warning.
tmp.cpp:15:48: error: Reference to temporary returned. [returnTempReference]
friend A &operator*(double b, A &m) { return m * b; }
When rewriting (*)
as
friend A &operator*(double b, A &m) { m * b; return m; }
The error from cppcheck disappears.
So, is this an actual problem and I'm overseeing something, or is it a false positive by cppcheck?
Some context: In my code, class A
is actually a Matrix class, for which I don't want to create a new object upon multiplying with a constant, thus returning the reference.
Your code does not return a reference to a temporary. One is inclided to think that, because what you implemented as operator*
is actually an operator*=
. If you did implment operator*
which does not modify the current A
but returns a new one, then returning a reference would be problematic.
I dont have the tool available, but I would expect it to not complain about:
#include <iostream>
using namespace std;
class A {
public:
double a;
A &operator*=(double b)
{
a *= b;
return *this;
}
friend A &operator*=(double b, A &m) { return m *= b; } // (*)
};
int main()
{
A a;
a.a = 5.0;
a *= 3.0;
std::cout << a.a << std::endl;
3.0 *= a;
std::cout << a.a << std::endl;
return 0;
}
Which really does the same as your code, but with the expected semantics of *=
.
As songyuanyao mentions in a comment, it might be that the tool simply expects m*b
to be a rvalue-expression, as it usually is, without actually checking the implementation of your *
.