2

GCC の__attribute__((pure))or__attribute__((const))で注釈を付ける基準を満たす C 関数があるとします。ただし、特定の入力パラメーターについては、関数が返す代わりに、またはそのようなものをlongjmp実行する場合があります。abortしたがって、通常「純粋な」関数と呼ぶものではありません。それでも、関数の戻り結果をいつキャッシュして再利用できるかを決定するために GCC がこれらの注釈のみを使用している場合は、これらの注釈をそのような関数に適用する可能性があります。返される場合、その関数は副作用のない、その引数の純粋な結果であると見なすことができます (さらに、pureまたはで注釈を付けているかどうかに応じて、おそらくグローバル状態const)。

そのような場合にこれらの注釈を適用できるかどうかについて、経験や知識を持っている人はいますか? (私は、いくつかのセットアップやコンパイルフラグで何がうまくいくかだけでなく、何がうまくいくかに興味があります。)

4

2 に答える 2

2

関数属性のドキュメントでは、非純粋な関数の例として「無限ループを持つ関数」が具体的に言及されているため、マークされた関数が返されない場合、適切な動作に頼ることはできないと言っても過言でpureはありません。そして、constそれのより厳密なバージョンとして説明されているので、おそらく同じことが当てはまるでしょう.

[…] GCCがこれらの注釈のみを使用して、関数の戻り結果をいつキャッシュして再利用できるかを決定している場合[…]

同じドキュメントによると、純粋な関数は「共通部分式の削除とループの最適化」の対象になる可能性があります。それらが何をカバーできるのか正確にはわかりません。たとえば、「ループの最適化」に、ループから純粋な関数を因数分解するためにステートメントを並べ替えようとするコンパイラーが含まれている場合、つまり、次のような場合

while (...) {
    ...;
    tmp = my_pure_function(17);
    ...;
}

のようなものに変換できます

tmp = my_pure_function(17);
while (...) {
    ...;
}

longjmp— 明らかに-ing 関数に注釈を付けると、他の__attribute__((pure))方法では実行されるはずのコードが実行されない可能性があります。

(そして — 本当によくわかりません — が存在する__attribute__((const))ことは、コンパイラpureこの種の並べ替えの最適化を喜んで実行することを示唆していると思います。との明らかな違いconstは、const関数はより自由に並べ替えることができるのに対し、pure関数はより自由に並べ替えることができることです。グローバル変数の (潜在的な) 変更にまたがって並べ替えることはできません。しかし、それは私の推論にすぎず、完全にずれている可能性があります。)

于 2014-03-16T03:36:11.407 に答える
1

純粋な関数では、戻り値の型を合理的に欠くことはできません。abort が決して戻らないことを考えると、'pure' として戻らない可能性のある関数を指定すると、関数が少し拡張されるように思えます。longjmp には副作用があり、純粋な関数には副作用があってはならないため、この関数は純粋な属性には適していないように思えます。

関数に const 属性を指定すると、順序が変更される場合があります。次に longjmp または abort を実行すると、順序が重要な別の関数の前にジャンプまたはアボートすることがあります。これにより、未定義の動作が発生する可能性があり、維持するのは悪夢のように聞こえます。

特定のケースでこれらの属性を使用すると、未定義の動作が発生する可能性があります。すべての状況で機能するものを探している場合は、その関数でこれらの属性を使用しないでください。

于 2014-03-16T03:39:40.393 に答える