Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a good way to make sure a C++ function result is not ignored?

Tags:

c++

lint

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.

like image 455
xan Avatar asked Jun 21 '11 23:06

xan


2 Answers

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.

like image 69
Dietrich Epp Avatar answered Jan 03 '23 20:01

Dietrich Epp


For Microsoft VC++, there is the _Check_return_ annotation: http://msdn.microsoft.com/en-us/library/ms235402(v=VS.100).aspx

like image 40
Nemanja Trifunovic Avatar answered Jan 03 '23 19:01

Nemanja Trifunovic