休日(でなくてもいいけれど)の読書の題材としてコンピュータ・プログラムを選んだとき、単にコードを読むだけでなく、何か図形的な補佐が欲しいと思うことがある。
オブジェクト指向の言語だとUML図が便利だが、別のパラダイムではあまり役に立たない。
たとえばC言語では、プログラムの構成要素である関数(というか手続き)の呼び出し合う関係を視覚化できると少しうれしい(「すごくうれしい」とまではいかない)。
次のようなコードがあったとする。
#include <stdio.h> int fib(int n) { if (n<3) return 1; return fib(n-2)+fib(n-1); } int main() { int i; for (i=1; i<=10; ++i) { printf("fibonacci(%d) = %d\n", i, fib(i)); } return 0; }
2つの関数fibとmainの呼び出し関係は次のようになっている。
- main→fib
- fib→fib
このような、有向グラフをコールグラフと呼ぶ。
GNU Binutilsに含まれるgprofを使えばコールグラフを生成できるのだが、そのためには一度プログラムを実行しなければならず、得られるコールグラフも、実行時に呼び出された関数のみのものだという欠点がある。
ついでに、グラフがあればそれを描画したいというのが人情だから(グラフが大きいとあまり意味がないのだが)、下のような絵が描けるとうれしい。
というわけで、コールグラフを描画するためのツールであるEgyptとCodeVizを試す。
準備
想定する環境はUbuntu。
共通の準備
2つのツールともグラフの描画まではやってくれない。どちらも描画はGraphVizに任せるようになっているため、まずはGraphVizをインストールする。
apt-get install graphviz
Egypt
Egyptのインストール手順は以下の通り。
wget http://www.gson.org/egypt/download/egypt-1.6.tar.gz tar zxf egypt-1.6.tar.gz cd egypt-1.6 perl Makefile.PL make sudo make install
Cygwinでは最後の「make install」で失敗した(というわけで想定環境はUbuntu)。
CodeViz
CodeVizのインストール手順は以下の通り。
wget http://www.csn.ul.ie/~mel/projects/codeviz/codeviz-1.0.11.tar.gz tar zxf codeviz-1.0.11.tar.gz cd codeviz-1.0.11/compilers wget http://ftp.yz.yamagata-u.ac.jp/pub/GNU/gcc/gcc-3.4.6/gcc-3.4.6.tar.gz cd .. ./configure --prefix=インストール先 make sudo make install export PATH=インストール先/gccgraph/bin:$PATH
使い方
Egypt
Egyptの使い方は以下の通り(詳しい使い方は「man egypt」)。
gcc -dr fib.c #fib.c.131r.expandができる egypt fib.c.131r.expand > egypt.dot dot -Tgif -Grankdir=LR egypt.dot -o egypt.gif
「-dr」はRTLを生成するためのオプション。「-Grankdir=LR」は階層を左から右に向かって描くためのオプション(デフォルトは上から下)。最後に紙に出力したいなら、「-Tps」としてPostscriptにするといいだろう。
CodeViz
CodeVizの使い方は以下の通り。
gcc fib.c #fib.c.cdepnができる genfull #full.graphができる。詳しい使い方は「genfull --man」 dot -Tgif -Grankdir=LR full.graph -o full.gif
今読んでいるコード中にあるものだけに限定したい場合は、gengraphを使う(-fは最上位の関数を指定、–plainはdotファイルを出力するための、–no-externは外部のファイルを無視するためのオプション。詳しい使い方は「gengraph –man」)
。
gengraph -f main --plain --no-extern #main.plainができる。 dot -Tgif -Grankdir=LR main.plain -o main.gif
Startrek
グラフが少しでも大きくなると実用性に疑問が生じてくる。
Chris NystromさんのSuper Star Trek Classicのコードで試す。このコードはBASICをそのままCに翻訳したものであるため、今日の基準では、読みやすいとは言えないだろう。それでも読みたいというときに、コールグラフが役立つはず。(Startrek自体に興味がある向きはWikipediaの記事を参照)
Egypt
CodeViz
コールグラフは扱われていないが、休日の読書のガイドにはDiomidis Spinellis『Code Reading』(毎日コミュニケーションズ, 2004)がおすすめ。(新版)