[kernel/main.c]_PROTOTYPEマクロに唸る
MINIXのご本尊のmainだと思われる、kernel/main.cから読み進めて行こう。ファイルの冒頭にも「This file contains the main program of MINIX as well as its shutdown code.」と書いてある。
24行目から始まるプロトタイプ宣言。初っぱなからマクロの登場だ。
FORWARD _PROTOTYPE( void announce, (void));
FORWARD
はinclude/minix/const.hで#define FORWARD static
と定義されている。これ以外の独自修飾子も、同様にconst.hで宣言されている。
- include/minix/const.h:9-12
#define EXTERN extern /* used in *.h files */ #define PRIVATE static /* PRIVATE x limits the scope of x */ #define PUBLIC /* PUBLIC is the opposite of PRIVATE */ #define FORWARD static /* some compilers require this to be 'static'*/
FORWARDは、関数のスコープをファイルスコープに押さえ込む役割のようだ。
続いて_PROTOTYPEマクロ。
名前からもわかるように、関数プロトタイプ宣言に関するマクロである。これの役割はK&R CとANSI Cのプロトタイプ宣言の違いを吸収するものっぽい。本体はinclude/ansi.hに記述されている。
#ifdef _ANSI /* Keep everything for ANSI prototypes. */ #define _PROTOTYPE(function, params) function params #define _ARGS(params) params (略) #else /* Throw away the parameters for K&R prototypes. */ #define _PROTOTYPE(function, params) function() #define _ARGS(params) () (略) #endif /* _ANSI */
この定義と、先のプロトタイプ宣言を見比べると、K&RとANSIそれぞれの場合で以下のように展開されることがわかる。
ANSIの場合 | static void announce (void); |
---|---|
K&R の場合 | static void announce(); |
ANSIの場合は普通のプロトタイプ宣言だが、K&Rにはプロトタイプ宣言なるものは存在しないので、この文は関数の使用宣言をしているらしい(K&Rの資料がないので詳細は不明)。
では実際の関数定義部はどうなっているかというと……announce関数は引数を持たないので、その次のshutdown関数を見てみる。
PRIVATE void shutdown(tp) timer_t *tp; { ...
こっちは完全にK&R準拠の書き方だ。後方互換の為に、ANSI Cでもこの書き方も許されている(無論、推奨はされていないが)ので、プロトタイプ宣言部分だけを切り替えてやれば、K&RなコンパイラでもANSIなコンパイラでもコンパイルできるって仕組みか。すげー!
0.MINIXのソースを読む
就活の面接で「OSのソースを読むと勉強になるYO!」と言われたのに触発され、読んでみる事にした。タスク管理とか前々から興味はあったしね。
Mac厨でありBSD厨でもある俺としては、FreeBSDとかDarwinのソースを読んでみたい所だけど、こいつらは流石に規模が大き過ぎるので、初学者には厳しいと判断。とりあえず、この手の話には最適なMINIXのソースを読む事にする。
MINIX 3公式サイトからMINIX 3.1.1の基本機能部分だけのソースtarballを落としてきて解凍。適当にXcodeでプロジェクトを作って、ソースファイルを丸ごと追加した。ソースコードを読むための、各種ツールなんかもあるみたいけど、とりあえずはXcodeだけで頑張って見る予定。
まずは、kernel/main.cあたりから読んで行けばいいのかな?OSに限った話じゃないが、初学者がある程度の規模のソフトのソースを読む際は、どっから読んでいいのか非常に困る所である。
ま、適当に読んで行くとしましょうか。