c – 为什么这个constexpr代码导致G​​CC占用我所有的RAM?

前端之家收集整理的这篇文章主要介绍了c – 为什么这个constexpr代码导致G​​CC占用我所有的RAM?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
以下程序将调用fun 2 ^(MAXD 1)次.但最大递归深度不应超过MAXD(如果我的想法是正确的).因此编译可能需要一些时间,但它不应该吃掉我的RAM.
#include<iostream>

const int MAXD = 20;

constexpr int fun(int x,int depth=0){
  return depth == MAXD ? x : fun(fun(x + 1,depth + 1) + 1,depth + 1);
}

int main(){
  constexpr int i = fun(1);
  std::cout << i << std::endl;
}

问题是吃掉我的RAM就是它的功能.当我将MAXD​​调高到30时,我的笔记本电脑在GCC 4.7.2快速分配3 gb后开始交换.我还没有尝试使用clang 3.1,因为我现在无法访问它.

我唯一的猜测是,这与GCC试图过于聪明并记住函数调用有关,就像它对模板一样.如果是这样的话,他们没有限制他们做了多少memoization,如MRU缓存表的大小或其他东西,这似乎并不奇怪吗?我还没有找到一个禁用它的开关.

我为什么要这样做?
我正在研究创建一个高级编译时间库的想法,比如遗传编程或其他东西.由于编译器没有编译时尾部调用优化,我担心任何循环都需要递归(即使我调高了最大递归深度参数,这看起来有点难看)将快速分配我的所有RAM和填充它与无意义的堆栈帧.因此,我想出了上面的解决方案,可以在没有深层堆栈的情况下获得任意多个函数调用.这种功能可用于折叠/循环或蹦床.

编辑:
现在我已经在clang 3.1中尝试了它,它根本不会泄漏内存,无论我多长时间工作(即我有多高MAXD). cpu使用率几乎为100%,内存使用率几乎为0%,就像预期的那样.也许这只是GCC中的一个错误.

解决方法

这可能不是关于constexpr的权威文件,但它是与 gcc constexpr wiki.相关的主要文件

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf

……它说……

We (still) prohibit recursion in all its form in constant expressions.
That is not strictly necessary because an implementation limit on
recursion depth in constant expression evaluation would save us from
the possibility of the compiler recursing forever. However,until we
see a convincing use case for recursion,we don’t propose to allow it.

所以,我希望你能够克服语言边界和gcc选择实现constexpr的方式(可能尝试生成内联的整个函数,然后评估/执行它)

猜你在找的C&C++相关文章