読者です 読者をやめる 読者になる 読者になる

C++と色々

主にC++やプログラムに関する記事を投稿します。

Visual C++ Complier Nov 2013 CTPのconstexprのコンパイル時再帰深度

Visual C++

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ですが、他の環境では限界再帰深度変わるのでしょうか?