0

say we have a set of function calls that are executed in the following order similar to a tree. that is func0 call func1 and func2 in order. and func2 results in calling func3, afterwhich func0 continues to its next line for executing func4.

func0   // depth 0
  func1  // depth 1
  func2  // depth 1
    func3  // depth 2
  func4    // depth 1
    func5  // depth 2
       func6  // depth 3
          func7  // depth 4
    func8 // depth 2
func9  // depth 0

What line of code can I put in each one of these functions to print such depth?

Alejandro
  • 879
  • 11
  • 27
  • One way I can think of is passing an argument of each function which will indicate the depth. Then you simply output the function name in the corresponding format. – Karen Baghdasaryan Oct 20 '21 at 15:41
  • 1
    https://www.boost.org/doc/libs/1_77_0/doc/html/stacktrace.html might help otherwise you need to tell us what platform you are targeting as there is no standard c++ api to interrogate the call stack – Alan Birtles Oct 20 '21 at 15:41
  • @AlanBirtles a non standard c++ snippet can also be useful. I was for example thinking if using some global variable I could do it. my main platform is linux but I may also use it in windows – Alejandro Oct 20 '21 at 15:51

1 Answers1

4

One way is to create an RAII class that counts the depth, and instantiate it at the top of each function you wish to track. I've done this sort of thing for debugging purposes.

class DepthCounter
{
    static int depth;

public:
    DepthCounter(const std::string& name)
    {
        std::cout << std::string(depth*2, ' ') << name << "  // depth " << depth << '\n';
        ++depth;
    }

    ~DepthCounter()
    {
        --depth;
    }
};

int DepthCounter::depth = 0;

You can instantiate this in each function with something like:

DepthCounter dc(__func__);

You can name the instance whatever you wish, but without giving it a variable name it will just be a temporary and get destroyed essentially at the semicolon. By making it a variable, it lives until the function exits by whatever means, whether by falling off the end, an explicit return, or via an exception.

I didn't show all the code (have to leave something for you to do), but the output I got looks like:

func0  // depth 0
  func1  // depth 1
  func2  // depth 1
    func3  // depth 2
  func4  // depth 1
    func5  // depth 2
      func6  // depth 3
        func7  // depth 4
    func8  // depth 2
func9  // depth 0
Fred Larson
  • 60,987
  • 18
  • 112
  • 174
  • Do you have a recommmendation about instantiating it? when I instantiate it as DepthCounter("counter") but without assigning it to a variable I think it already destructs the class when it goes to the next line of code inside the same function – Alejandro Oct 20 '21 at 16:33
  • I just did `DepthCounter dc(__func__);` in each function. Without giving it a variable name, you're just creating a temporary and it gets destroyed essentially at the semicolon. By making it a variable, it lives until the function exits by whatever means, whether by falling off the end, an explicit `return`, or via an exception. – Fred Larson Oct 20 '21 at 16:34
  • can you suggest a way that if I instantiate it, again in the same function, it returns the same depth? because at the moment the constructor always adds to the depth – Alejandro Oct 20 '21 at 20:19
  • Don't instantiate it more than once in the same function. Just once, first thing in each function. – Fred Larson Oct 20 '21 at 20:22
  • yea but my main purpose is actually doing something in the same function multiple times, for example logging while having the same depth number, preferably using one line also. like could the constructor get something that tells its still in the current function not to increment depth? – Alejandro Oct 20 '21 at 20:27