libA、libBの2つの内作ライブラリを用いるappSampleというアプリケーションをC++で作成するものとします。
そしてappSampleのソースファイル "App.cpp" が次のヘッダファイルをインクルードするものとします。
このとき、 #include
の記述順序をどうしますか?
「気にしたことがない」という場合を除き、概ね次のどちらかになるのではないかと思います。*1
1 2 3 4 5 6 |
|
1 2 3 4 5 6 |
|
依存関係の末端から先にインクルードするのが【X】、根元から先にインクルードするのが【Y】です。
このどちらがより良いインクルード順序であると考えられるでしょうか?
私は【X】を推します。
理由としては、例えば上のコード例における "libB/xxx.h" が次のような内容になっている場合があるからです。
このヘッダファイルだけ見れば「HANDLE
型を使っているのに "windows.h" をインクルードしてないとかアホか!」と思うことでしょう。
しかし、開発が大規模になり依存関係が増えてくると、こういったヘッダファイルの記述忘れは往々にして起こりえます。
このとき【Y】のインクルード順序だと、 "libB/xxx.h" よりも先に "windows.h" がインクルードされているため、問題なくコンパイルが通ってしまいます。
"libB/xxx.h" の記述ミスは、 "libB/xxx.h" が他の「"windows.h" をインクルードしていないソースコード」でインクルードされるまで気付かれません。
libBをappSampleの実装のみに用いているうちはそれでもいいかもしれませんが、将来的に他の実装で用いることになった場合に余計な手間が発生するリスクがあります。
もっとも【X】のインクルード順序であっても、例えば "App.h" に #include <windows.h>
が記述されていた場合は同じ問題が起こりえます。
なので【X】も完璧であるとは言えません…が、少なくとも【Y】よりは記述忘れの早期発見確率は高くなるはずです。
特にC++であれば普通は "libB/xxx.h" で宣言されたクラス(構造体)の実装を記述する "xxx.cpp" を用意するはずなので、そこで【X】のインクルード順序を採っていればまず間違いなく気付くことができます。
以上から、ヘッダファイルのインクルードは依存関係の末端に近いものほど先に行うことを私は推奨します。