【问题标题】:Why can g++ 5.4 not compile this compile-time prime number code?为什么 g++ 5.4 不能编译这个编译时素数代码?
【发布时间】:2017-07-09 04:30:57
【问题描述】:
#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,它就会编译。但我想使用更大的数组来节省时间。

任何想法都会受到赞赏。

【问题讨论】:

  • 你看到了什么错误?
  • 情况是这样的。编译器需要永远编译。使用了大量的记忆,最后只是崩溃..
  • 您要求 gcc 使用元编程自行查找 1 到 50000 之间的所有素数。相当令人印象深刻,但这不是编译器的用途。你,先生/女士,今天赢得了互联网。
  • @AnT Coffee?更像是一种味道几乎但不完全不同于茶的饮料。
  • 如果您确实需要前 50000 个素数,我建议您离线计算或下载它们并将它们存储在 constexpr 变量中。这是 kust 浪费的编译时间。

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


【解决方案1】:

这是实施质量 (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(您的示例已为此编译)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-06
    • 2011-11-27
    • 2010-10-24
    • 2019-11-15
    相关资源
    最近更新 更多