为什么g ++ 5.4不能编译这个编译时的素数代码?

时间:2017-02-20 02:02:17

标签: c++ templates compiler-errors constexpr compile-time-constant

#include<iostream>
using namespace std;

template<int N> class Prime
{ // generate N prime numbers at compile time
public:
    unsigned int arr[N]{};
    constexpr Prime() {
        int k=0;
        for(unsigned int i=2; k<N; i++) {
            bool isPrime = true;
            for(int j=0; j<k; j++) {
                if(arr[j] > i/2) break;
                if(i % arr[j] == 0) {
                    isPrime = false;
                    break;
                }
            }
            if(isPrime) arr[k++] = i;
        }
    }
};
int main()
{
    Prime<50000> prime; // if 50000->5000, ok
    for(auto& a : prime.arr) cout << a << ' ';
}

G ++无法编译此代码。它花了很多时间尝试编译,使用大量内存,最后只是崩溃。

如果我将数字50000缩小,或者除去constexpr,它就会编译。但我想使用更大的阵列来节省时间。

任何想法都将受到赞赏。

1 个答案:

答案 0 :(得分:6)

这是一项实施质量(QoI)问题。来自draft Standard

  

附件B(资料性附录)实施数量[implimits]

     

1因为计算机是有限的,C ++的实现是不可避免的   他们可以成功处理的程序大小有限。   每个实施都应记录已知的限制。   本文档可能会引用固定的限制,如何存在   计算变量限制作为可用资源的函数,或者说   固定限制不存在或未知。

     

2限制可能会限制包含所述数量的数量   以下或其他人。每个数量后面的括号内的数字是   建议作为该数量的最小值。但是,这些   数量只是指导原则,不能确定合规性。

     

(2.38) - 递归constexpr函数调用[512]。

     

(2.39) - 在核心常量表达式内评估的完整表达式   [1 048 576]。

您的算法超出核心常量表达式中计算的完整表达式的限制。请注意,gcc确实超出了最低要求,因为您的循环会缩放为1/2 * N^2,而gcc会将其编译为N = 5,000。我无法找到gcc记录的硬限制。不幸的是,与具有-fconstexpr-steps的clang不同,您无法覆盖gcc的constexpr评估数。

结论:向gcc提交效果报告或使用clang(您的示例会为其编译)。