如何跟踪递归深度?

时间:2011-10-19 23:11:04

标签: c++

我有一个递归功能,我正在排除故障。我想输出递归深度...即。函数调用自身的次数。

如果我使用一个静态变量,它在函数顶部递增,在底部递减。

这会准确地给我深度水平吗?

recurse()
  {
  static int depth = 0;
  depth++;
  /*
  do stuff
  recurse()
  */
  depth--;
  return return_value;
  }

7 个答案:

答案 0 :(得分:8)

recurse(int depth = 0){
    ....
    recurse(depth+1);
}

答案 1 :(得分:8)

使其更容易和

<子> 如果你真的在扩展你的想象力,这可以使编译器更容易内联一些递归调用,和/或在尾递归的情况下执行尾调用优化。 我没有证据证明这是一个角色,但我可以想象在函数体内引用外部符号影响编译器优化。

我建议:

stuff recurse(int level=0)
{

     //...
     recurse(level+1);

     //... (return stuff?)
     //... (throw exceptions?)

     //...
     recurse(level+1);

     //... (return stuff?)

}

答案 2 :(得分:5)

不,如果抛出异常,则可能不会。更好(也更常见)的选择是:

int recurse(int depth=0)
{
    recurse(depth+1)
    return return_value;
}

答案 3 :(得分:2)

如果您想以非侵入方式执行此操作,您实际上可以要求您的编译器为您调整每个电话,例如:与gcc:

#include <iostream>
static __thread int depth=-1;
extern "C" {
    void __cyg_profile_func_enter (void *, void *) __attribute__((no_instrument_function));
    void __cyg_profile_func_exit (void *, void *) __attribute__((no_instrument_function));
    void __cyg_profile_func_enter (void *func,  void *caller)
    {
        depth++;
    }


    void __cyg_profile_func_exit (void *func, void *caller)
    {
        depth--;
    }
}

class Foo {
public:
    void bar() {
        std::cout << "bar: " << depth << std::endl;
    }
};

int main() {
    Foo f;
    f.bar();
    return 0;
}

您需要使用-finstrument-functions进行编译才能实现此目的。

答案 4 :(得分:0)

在单线程上下文中,它将起作用。

答案 5 :(得分:0)

为了线程安全的目的,您通常希望增加在递归函数之外定义的深度变量,并从该函数外部打印它。

这是一个简单的因子示例:

#include <stdio.h>

unsigned factorial(unsigned x, unsigned* depth)
{
  if (x <= 1)
    return 1;

  ++*depth;

  return x * factorial(x - 1, depth);
}

int main(void)
{
  unsigned depth, f;

  depth = 0; f = factorial(1, &depth);
  printf("factorial=%u, depth=%u\n", f, depth);

  depth = 0; f = factorial(2, &depth);
  printf("factorial=%u, depth=%u\n", f, depth);

  depth = 0; f = factorial(6, &depth);
  printf("factorial=%u, depth=%u\n", f, depth);

  return 0;
}

输出:

C:\>recdep.exe
factorial=1, depth=0
factorial=2, depth=1
factorial=720, depth=5

答案 6 :(得分:-1)

是的,它应该有效。我没有看到任何问题。