4

私は再帰を少し遊んでいて、それがどのようにコンパイルされるかを確認しようとしていますが、どのような状況でコンパイル時または実行時に再帰を計算するかがconstexprわかりません。gcc

私は次の階乗計算コードを使用しています:

#include <iostream>

constexpr unsigned int factorial(unsigned int i)
{
  return i > 0 ? i*factorial(i-1) : 1;
}

int main(void)
{
  std::cout << factorial(X) << std::endl;
}

x階乗の値を変更します。

  • 最適化せずにコンパイルする場合、式はコンパイル時に計算されません。
  • フラグを使用してコンパイルする場合-O1、式はコンパイル時にまだ計算されません。
  • -O2場合、式はコンパイル時に計算されますx < 9。この値の後、階乗はループとしてインラインで実装されます。フラグの値を変更-fconstexpr-depthしても、何も変わりません。
  • を使用-O3すると、式はコンパイル時に計算されますif x < 7。この値の後に、階乗はx86xmm拡張でインラインで実装されます。
  • 階乗関数の合計の積を変更すると、コンパイル時の計算が最大10000以上になり、の値を-fconstexpr-depth増減しても何も変わりません。

再帰関数をコンパイル時または実行時に実装するためのgcc4.7のルールを知っている人はいますか?

4

2 に答える 2

2

constexprコンパイル時に必要な場合にのみ、コンパイル時に評価されることが保証されます。たとえば、enum値は一定でなければならないため、これはコンパイル時に計算されることが保証されています。

enum { VALUE = factorial(X) };
cout << VALUE << endl;

コンパイル時に必要ない場合は、次のように宣言するのと同じ効果がありますinline。これは単なるヒントであり、コンパイラーは自由に必要なことを実行できます。

と同じようinlineに、最近のほとんどのコンパイラはあなたのヒントを完全に無視します。パフォーマンス上の理由から、コンパイラーは、要求されていない場合でもインライン化できることを望んでおり、それが価値があるかどうかを判断する独自のアルゴリズムを持っているので、なぜinlineキーワードをまったく見ないのでしょうか。 ?

于 2013-01-20T04:31:36.283 に答える
1

関数を宣言するconstexprことは、コンパイル時に評価されることを意味するものではありません。これは、コンパイル時に必要な値を計算するために使用できることを意味します。他のコンテキストでは、これは単なる通常の関数であり、コンパイル時に評価することが「as-if」ルールを満たしているとコンパイラが判断しない限り、実行時に評価され、実行する価値があります。

constexprつまり、階乗関数の宣言を省略した場合、コンパイル時/実行時の実行のパターンがまったく同じになると思います。

于 2013-01-20T00:59:41.593 に答える