#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中的一个错误.
解决方法
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.