9

C ++ 11の1つはgcc、関数(クラスメソッドではない)constを、それが純粋であり、グローバルメモリを使用せず、その引数のみを使用することを示すものとしてマークできますか?

を試してみましたが、gccまさにが欲しいものです。ただし、関数内でグローバル メモリに触れても、コンパイル時エラーは発生しません。__attribute__((const))

編集 1

ご注意ください。私は純粋関数を意味します。定数関数ではありません。GCC の属性は少しわかりにくいです。純粋関数は引数のみを使用します。

4

3 に答える 3

7

お探しconstexprですか?これは、関数がコンパイル時に評価される可能性があることをコンパイラに伝えます。関数にはリテラルの戻り値とパラメーターのconstexpr型が必要であり、本体には宣言とディレクティブを使用した静的アサート、typedef、および 1 つの return ステートメントのみを含めることができます。constexpr関数は、定数式で呼び出すことができます。

constexpr int add(int a, int b) { return a + b; }

int x[add(3, 6)];

の意味を見てみると__atribute__((const))、答えはノーです。標準の C++ ではこれを行うことはできません。を使用しconstexprても同じ効果が得られますが、はるかに限定された関数セットでのみ使用できます。ただし、コンパイルされたプログラムが同じように動作する限り (as-if ルール)、コンパイラがこれらの最適化を独自に行うことを妨げるものは何もありません。

于 2012-12-02T23:01:17.480 に答える
2

標準の C++11 のみを使用:

namespace g{ int x; }

constexpr int foo()
{
    //return g::x = 42;  Nah, not constant
    return 42;      // OK
}

int main()
{}

別の例を次に示します。

constexpr int foo( int blah = 0 )
{
    return blah + 42;      // OK
}

int main( int argc, char** )
{
    int bah[foo(2)];            // Very constant.
    int const troll = foo( argc );  // Very non-constant.
}

GCC の意味は__attribute__( const )GNU コンパイラ ドキュメントに次のように記載されています。

多くの関数は、引数以外の値を調べず、戻り値以外には何の効果もありません。pure関数はグローバル メモリの読み取りを許可されていないため、基本的に、これは以下の属性よりもわずかに厳密なクラスです。

これは、関数の結果が引数のみに依存する必要があり、関数に副作用があってはならないことを意味すると解釈される場合があります。

これにより、 C++11 よりも一般的な関数のクラスが可能にconstexprなり、関数が になり、inline引数と関数の結果がリテラル型に制限され、関数本体の「アクティブな」ステートメントが単一のreturnステートメントに制限されます。ここで、(C++11 §7.1.5/3)

— 戻り値の初期化に使用されるすべてのコンストラクター呼び出しと暗黙の変換 (6.6.3、8.5) は、定数式 (5.19) で許可されているもののうちの 1 つでなければなりません。

例として、関数を作成することは困難です (不可能ではないと思いますが、難しいと思います) constexpr sin

しかし、結果の純度は 2 つの当事者にのみ関係します。

  • 純粋であることがわかっている場合、コンパイラは既知の結果で呼び出しを除外できます。
    これは主に、マクロで生成されたコードの最適化です。マクロを関数に置き換えてinline、同じ部分式のばかげた生成を回避します。

  • 純粋であることがわかっている場合、プログラマーは呼び出しを完全に削除できます。
    これは適切なドキュメンテーションの問題です。:-)

そのため、eg の純粋性をsin言語で表現する方法を探す代わりに、マクロによるコード生成を避け、純粋な関数をそのように文書化することをお勧めします。

そしてconstexpr、実際に可能な関数に使用してください (残念ながら、2012 年 12 月現在、最新の Visual C++ コンパイラはまだサポートしていませんconstexpr)。


pureの関係constexprについては、以前の SO の質問があります。主に、すべてのconstexpr関数はpureですが、その逆ではありません。

于 2012-12-02T23:00:44.950 に答える