LoginSignup
1

More than 5 years have passed since last update.

[C++]2重ループ内にcontinueがあるconstexpr関数をgccでコンパイルすると死ぬ

Last updated at Posted at 2017-03-08

C++14で連立方程式をコンパイル時に解くコードを書いていた時に、偶然コンパイラの奇妙な振る舞いを見つけた。
最終的に、そのコードは以下のようなところにまで還元された。

prog.cc
#include <iostream>

constexpr int foo(){
    for(int i = 0; i < 1; i++){
        if(i == 0) continue;
        for(int j = 0; j < 1; j++);
    }
    return 334;
}

int main(){
    constexpr int a = foo();
    std::cout << a << "\n";
    return 0;
}

foo()は2重ループとcontinue文を含んでいるが、実際には常に334を返すだけのconstexprな関数だ。
それを使ってconstexpr int a = foo();と宣言することにより、aの値はコンパイルの時点で334に確定する。...はずだった。

実際clang6.2.0までのgccでこれは正しくコンパイルできる。
ところが、gcc 7.0.1では

prog.cc: In function 'int main()':
prog.cc:12:26:   in constexpr expansion of 'foo()'
prog.cc:6:9: error: constexpr loop iteration count exceeds limit of 262144 (use -fconstexpr-loop-limit= to increase the limit)
         for(int j = 0; j < 1; j++);
         ^~~

というコンパイルエラーが出てしまい、またgcc 6.3.0に至っては何も言わずに黙り込んでしまう。なぜかfoo()内のループが無限ループ化してしまっているようだ。
ちなみにこのfoo()内のif(i == 0) continue;for(int j = 0; j < 1; j++);のどちらかを取り除くとgcc 6.3.0, gcc 7.0.1でもうまくコンパイルでき、またmain()内のaのconstexprを取り除いてもうまくいく。

おそらくgccのバグだと思う。近いうちに報告してみようか...?

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1