C++で関数呼び出しツリーの作成

以下のクラスを使用するだけで、関数呼び出しのツリーを出力できることに気付いた。

#if defined DEBUG
#  define __FUNCTION_TRACER(s) FunctionTracer __function_tracer(s)
#else
#  define __FUNCTION_TRACER(s)
#endif

class FunctionTracer {
private:
    static unsigned int depth;
    string name;

protected:
    void printDepth() const {
        int i;
        for (i=0; i?n", name.c_str());
        ++depth;
    }

    ~FunctionTracer() {
        --depth;
        printDepth();
        printf("?n", name.c_str());
    }
};
unsigned int FunctionTracer::depth = 0;

使い方は簡単。すべての関数の先頭に以下のような行を加えるだけ。

__FUNCTION_TRACER("function-name");

これで、関数が呼び出されるとFunctionTracerのコンストラクタが呼び出されて、関数を抜けるときにデストラクタが呼び出される。

(実際に使うかどうかは別として)グッドアイディア! と思ったのだが、何の気無しにGoogleで"function tracer"で検索したら213,000件ヒット(汗)。I'm Feeling Luckyしてみたら以下のページで全く同じアイディアの実装があった。

Function Calling Sequence Tracer Class

まぁ、ありきたりなアイディアなのかもなぁ。

追記

以下のようの__func__を使ったほうが奇麗との指摘があった(thanks>id:PaiN氏)。たしかに…。

#  define __FUNCTION_TRACER() FunctionTracer __function_tracer(__func__)

そして関数先頭では

__FUNCTION_TRACER();

と、書けば良いと。どうせなら__LINE__, __FILE__なども使えば尚良し。