11

私はgcc4.6.1を使用していて、constexpr関数の呼び出しを含むいくつかの興味深い動作を取得しています。このプログラムは問題なく実行され、すぐに印刷され12200160415121876738ます。

#include <iostream>

extern const unsigned long joe;

constexpr unsigned long fib(unsigned long int x)
{
   return (x <= 1) ? 1 : (fib(x - 1) + fib(x - 2));
}

const unsigned long joe = fib(92);

int main()
{
   ::std::cout << "Here I am!\n";
   ::std::cout << joe << '\n';
   return 0;
}

このプログラムの実行には永遠に時間がかかり、値が出力されるのを待つのに我慢できませんでした。

#include <iostream>

constexpr unsigned long fib(unsigned long int x)
{
   return (x <= 1) ? 1 : (fib(x - 1) + fib(x - 2));
}

int main()
{
   ::std::cout << "Here I am!\n";
   ::std::cout << fib(92) << '\n';
   return 0;
}

なぜそんなに大きな違いがあるのですか?2番目のプログラムで何か間違ったことをしていますか?

編集:私はこれをg++ -std=c++0x -O364ビットプラットフォームでコンパイルしています。

4

4 に答える 4

14

joe整数定数式です。配列境界で使用できる必要があります。そのため、合理的なコンパイラはコンパイル時にそれを評価します。

2 番目のプログラムでは、コンパイラがコンパイル時に計算できたとしても、そうしなければならない理由はありません。

于 2011-08-15T13:04:07.413 に答える
4

私の最善の推測では、プログラム番号 1 はコンパイル時に fib(92) が評価され、コンパイラが既に評価された値を追跡するための多くのテーブルやものが含まれているということです...プログラムの実行をほとんど簡単にします。

2番目のバージョンは、評価された定数式のルックアップテーブルなしで実際に実行時に評価されます。つまり、 fib(92) の評価は 2**92 回の再帰呼び出しのようなものを行います。

つまり、コンパイラは fib(92) が定数式であるという事実を最適化しません。

于 2011-08-15T13:06:07.907 に答える
2

何かが「複雑すぎる」と判断した場合、コンパイラがコンパイル時に評価しないことを決定する余地があります。これは、実際に実行できる正しいプログラムを生成するために評価を行うことが絶対に強制されていない場合です (@MSalters が指摘しているように)。

コンパイル時の遅延に影響を与える決定は、おそらく再帰の深さの制限になると思いました。(仕様では 512 として提案されていますが、必要に-fconstexpr-depth応じてコマンド ライン フラグを使用して値を上げることができます)。プログラムを実行します。したがって、あなたのケースには影響しません。

コードで最適化を行うという保証が必要な場合は、そのための手法を見つけたようです。しかし、constexpr-depth助けにならない場合は、関連するコンパイラフラグがあるかどうかはわかりません...

于 2011-08-15T13:20:19.020 に答える
2

I also wanted to see how gcc did optimize the code for this new constexpr keyword, and actually it's just because you are calling fib(92) as parameter of the ofstream::operator<<

::std::cout << fib(92) << '\n';

that it isn't evaluated at the compilation time, if you try calling it not as a parameter of another function (like you did in)

const unsigned long joe = fib(92);

it is evaluated at compile time, I did a blog post about this if you want more info, I don't know if this should be mentioned to gcc developers.

于 2012-03-09T10:14:33.810 に答える