7

最近、constメンバー関数が操作を実行して結果を返すというケースに遭遇しました。例えば、

class Foo { ...
    Foo add(Foo const & x) const;
}

しかし、他の誰かが、thisオブジェクトを更新しているように(結果を無視して)誤って呼び出していました。

Foo a = ...;
Foo b = ...;
a.add(b);

(このバグは、実際には不完全なリファクタリングによって発生しました。)

上記の最後の行でエラーまたは警告をトリガーする方法はありますか?次善の策は実行時のキャッチです。これは主に次のテンプレートで対処されます。ただし、カウンターの結果からわかるように、戻り値の最適化は無効になります。

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;
}

マクロを使用することで非効率性を改善できると思います。これにより、MustTake <>はデバッグのみで、リリースは不要になります。

コンパイル時のソリューションを探しています。それが失敗した場合、私は最良のランタイムソリューションを探しています。

4

3 に答える 3

8

これは、GCC と Clangの (ドキュメント) の関数属性ですが、MSVC などには移植できません。

class Foo { ...
    __attribute__((warn_unused_result))
    Foo add(Foo const & x) const;
}

ドキュメントにはrealloc 、たとえば使用されていると書かれていますが、私のシステムの他の標準機能には表示されません。

関数呼び出し全体のデータ フローを追跡し、より適切な警告を表示できる Clang 静的アナライザーの使用にも関心があるかもしれません。

于 2011-06-22T00:22:40.873 に答える
7

Microsoft VC++ の場合、_Check_return_注釈があります: http://msdn.microsoft.com/en-us/library/ms235402(v=VS.100).aspx

于 2011-06-22T00:27:29.890 に答える