2

でコンパイルすると、GCC は、最適化のため-Wsuggest-attribute=pureに でマークできる潜在的な関数を提案します。__attribute__ ((pure))

GCC のドキュメントでの定義は次のとおりです。pure

多くの関数は戻り値以外には影響を与えず、その戻り値はパラメーターやグローバル変数のみに依存します。このような関数は、算術演算子と同様に、一般的な部分式の削除とループの最適化の対象となります。これらの関数は属性 pure で宣言する必要があります。

メンバーinput_contextを含むクラスがある小さなゲームエンジンを作成しています。input_stateこのinput_contextクラスinput_stateは、オペレーティング システムからグローバルな入力状態を取得することにより、フレームごとにメンバーを更新します。

また、入力状態を照会するための「ゲッター」もいくつか含まれています。

簡単な例:

class input_context
{
private:
    input_state _input_state;

public:
    void update()
    {
        os::fill_input_state(_input_state);
    }

    auto mouse_x() const noexcept
    { 
        return _input_state._mouse_x;
    }

    auto mouse_y() const noexcept
    { 
        return _input_state._mouse_y;
    }

    auto is_key_down(keycode k) const noexcept
    { 
        // `_keys` is an array of `bool` values.
        return _input_state._keys[k];
    }
};

mouse_x()GCC は、 、 、 などのこれらすべての「ゲッター メソッド」が の候補であるmouse_y()と言っています。is_key_down()__attribute__ ((pure))

これらのメソッドを としてマークする必要がありpureますか?

私はそうは思いませんが、GCC の提案を見て疑問に思いました。

GCC の定義を解釈する方法がわかりません。パラメーターやグローバル変数のみにpure依存する関数はそのようにマークする必要があると書かれています。

  • ある意味では、グローバル OS 入力状態はグローバル変数として解釈できます。

  • 一方、「getter メソッド」は、_input_stateメンバー変数に応じて、常に異なる値を返します。

4

2 に答える 2

1

純粋とマークしても問題ないと思います。いくつかの IO 関数が追加された単純化された形式で例を検討します。

#include <stdio.h>
class X {
  int x_=0;
public:
  int x() const noexcept __attribute__ ((pure)) /*__attribute__((noinline))*/;
  void inc() noxcept { x_++; }
};
int X::x() const noexcept { puts("getting x"); return x_;}
int main(){
  X x;
  printf("%d\n", x.x() + x.x() + x.x());
  x.inc();
  printf("%d\n", x.x() + x.x() + x.x());
}

pureを使用すると、以下を取得できます。

getting x
0
getting x
3

それ以外の

getting x
getting x
getting x
0
getting x
getting x
getting x
3

最適化レベルでは少なくとも -O1 (より高いレベルでは__attribute__((noinline))、インライン化を防ぐために追加する必要がある場合があります)。

コンパイラーが状態の変化を検出できる限り、これらのゲッターへの 2 つの連続した呼び出しの間で状態が変化しても問題ありません。状態を変更するためにメソッドを実行する必要がある場合non-const、それは純度違反ではありません。ただし、on its ownコンパイラが変更を認識できない方法で状態が変更された場合 (システムが変更した/別のスレッドが変更した/シグナルハンドラーが変更した場合)、そのpure属性はもはや正当ではありません。

于 2016-02-01T18:23:38.857 に答える