I ran into a case recently where I had a const member function performing an operation and returning a result. For example,
class Foo { ...
Foo add(Foo const & x) const;
}
But someone else was inadvertently calling it like it was updating the this
object (ignoring the result):
Foo a = ...;
Foo b = ...;
a.add(b);
(This bug was actually introduced by an imperfect refactoring.)
Is there a way to make the last line above trigger an error or a warning? The next best thing would be a run-time catch, which is mostly addressed by the following template. However, it kills the return value optimization, as seen by the counter result.
template<typename T>
class MustTake {
T & obj;
bool took;
public:
MustTake(T o) : obj(o), took(false) {}
~MustTake() { if (!took) throw "not taken"; }
operator T&() { took = true; return obj;}
};
struct Counter {
int n;
Counter() : n(0) {}
Counter(Counter const & c) : n(c.n+1) {}
~Counter() {}
};
Counter zero1() {
return Counter();
}
MustTake<Counter> zero2() {
return Counter();
}
int main() {
Counter c1 = zero1();
printf("%d\n",c1.n); // prints 0
Counter c2 = zero2();
printf("%d\n",c2.n); // prints 1
zero1(); // result ignored
zero2(); // throws
return 0;
}
I suppose I can ameliorate the inefficiency by using a macro so that MustTake<> is debug only and a no-op for release.
I am looking for a compile-time solution. Failing that, I am looking for the best run-time solution.
This is what function attributes are for (documentation) in GCC and Clang, but it's not portable to e.g. MSVC.
class Foo { ...
__attribute__((warn_unused_result))
Foo add(Foo const & x) const;
}
The documentation says it's used on realloc
for example, but it doesn't appear on any other standard functions on my system.
You may also be interested in using the Clang static analyzer, which tracks data flow across function calls and can give you better warnings.
For Microsoft VC++, there is the _Check_return_
annotation: http://msdn.microsoft.com/en-us/library/ms235402(v=VS.100).aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With