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("%s>?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__なども使えば尚良し。