【发布时间】:2011-05-28 16:46:13
【问题描述】:
我在 C++ 中处理尾递归函数,我在使用 g++ 编译器时遇到了一些问题。
当numbers[] 的大小超过几百个整数时,以下代码会导致堆栈溢出。检查 g++ 生成的汇编代码,发现 twoSum_Helper 正在对自身执行递归 call 指令。
问题是以下哪一项导致了这种情况?
- 以下我忽略的错误会阻止尾递归。
- 我使用 g++ 的一个错误。
- 在 g++ 编译器中检测尾递归函数存在缺陷。
我在 Windows Vista x64 上通过带有 g++ 4.5.0 的 MinGW 使用 g++ -O3 -Wall -fno-stack-protector test.c 进行编译。
struct result
{
int i;
int j;
bool found;
};
struct result gen_Result(int i, int j, bool found)
{
struct result r;
r.i = i;
r.j = j;
r.found = found;
return r;
}
// Return 2 indexes from numbers that sum up to target.
struct result twoSum_Helper(int numbers[], int size, int target, int i, int j)
{
if (numbers[i] + numbers[j] == target)
return gen_Result(i, j, true);
if (i >= (size - 1))
return gen_Result(i, j, false);
if (j >= size)
return twoSum_Helper(numbers, size, target, i + 1, i + 2);
else
return twoSum_Helper(numbers, size, target, i, j + 1);
}
【问题讨论】:
-
您是否已经尝试单独执行条件增量并且只使用增量参数执行一次递归调用?它不如你的例子好,但它可能会对你的问题有所启发。
-
@stefaanv 是的,无济于事。似乎调用发生在 else 语句上,但没有任何调整会导致它使用 jmp 而不是调用。
-
如果您使用单个语句ala
return twoSum_Helper(numbers, size, target, i + j_ge_size, j_ge_size ? i + 2 : j + 1)其中j_ge_size是bool j >= size是否有效? (适合自己从 bool 进行隐式转换)。 -
-
Tom 在stackoverflow.com/questions/34125 中做了一个有趣的观察——他的尾递归需要函数是静态的...?
标签: c++ recursion functional-programming g++ tail-recursion