Visual C++ Complier Nov 2013 CTPにて部分的に実装されたconstexprですが、constexpr関数のコンパイル時再帰深度について調べてみました。
constexpr int func(int n) { return n == 0 ? 0 : func(n - 1); } int main() { static_assert(func(512) == 0, "");//511では通る }
エラー文
警告 1 warning C4591: 'constexpr' call-depth limit of 512 exceeded; use -Zc:constexprLimit<NUMBER> to increase the limit 警告 2 warning C4592: 'func': 'constexpr' call evaluation failed; function will be called at run-time エラー 3 error C2057: expected constant expression
コンパイル時再帰深度を超えたconstexpr関数はコンパイル時に実行されるべきコンテキストでもコンパイル時に実行されず、実行時に実行されるようです。そのため「static_assertに定数式を入れろ」というコンパイルエラーになっています。
1つ目の警告がヒントになっており、-Zc:constexprLimitコマンドラインオプションで、コンパイルエラーとなるconstexpr関数のコンパイル時再帰深度を設定できるようです。
早速-Zc:constexprLimit123456789をつけて以下のソースコードをコンパイルしてみました。
constexpr int func(int n) { return n == 0 ? 0 : func(n - 1); } int main() { static_assert(func(123456789) == 0, ""); }
コンパイルエラー
エラー 1 error C1063: compiler limit : compiler stack overflow
どうやらコンパイル時にスタックオーバーフローをしてしまったようです。この後、スタックオーバーフローをする境界を探しました。私の環境では59843回が限界再帰深度でした。 私のPCはメモリ8GBですが、他の環境では限界再帰深度変わるのでしょうか?