[迷信] 引用符で囲んだヘッダ名はカレントディレクトリから探索する
あるディレクトリ(~/srcとします)に、foo.cとbar.hという二つのソースファイルがあったとします。bar.hは、foo.cから次のようにインクルードしています。
ここで、別のディレクトリ(~/workとします)でfoo.cをコンパイルしたとしましょう。このとき、foo.cからインクルードしているbar.hは、期待通り~/src/bar.hを探し当てることができるでしょうか?
今度は、~/src/bar.hとは別に、~/work/bar.hというファイルを用意してみましょう。そして、先ほどと同じように、~/workで~/src/foo.cをコンパイルしてみます。このときに~/src/foo.cから取り込むbar.hは、~/src/bar.hでしょうか? それとも、~/work/bar.hでしょうか?
もし、引用符で囲まれたヘッダ名はカレントディレクトリから探索するのであれば、~/work/bar.hが取り込まれるはずですが、本当にそうなるでしょうか?
結論は、処理系によります。コンパイラが何であるかだけでなく、コンパイルオプションや環境変数等の設定まで特定しなければ、どうなるかはわかりません。JIS X3010:2003の6.10.2 ソースファイル取り込みから引用すると、
次の形式の前処理指令
# include "q文字列" 改行
は,二つの"区切り記号の間で指定した文字列で一意に決まるソースファイルの内容全体で,この指令を置き換える。指定したソースファイルの探索手順は処理系定義とする。この探索をサポートしていない場合,又は探索が失敗した場合,同じ文字列(もしあれば>文字を含めて)を含む次の指令に読み替えたのと同じ規則で再処理する。
C++に関してもほぼ同じと考えてかまいません。ちなみに、< >で囲まれたヘッダ名の探索手順も処理系定義です。もっといえば、< >で囲まれたヘッダ名がファイルであるかどうかも処理系定義になります。
ところで、現実の処理系ではどうかというと、引用符で囲んだヘッダ名をカレントディレクトリからだけ探索し、見つからなければ< >で囲んだ場合と同じ手順に移行する処理系も実在します。ただ、もっともよく見かけるのは、次のようなものです。
a.c → b.h → c.hの順に取り込もうとしている場合、
- a.cがあるディレクトリからb.hを探します。見つからなければカレントディレクトリを探します。
- b.hがあるディレクトリからc.hを探します。見つからなければa.cがあるディレクトリからc.hを探します。それでも見つからなければカレントディレクトリを探します。
多くのコンパイラでは、< >で取り込むヘッダはファイルとして実装されており、コンパイルオプション等で探索ディレクトリを追加することができるようになっています。コンパイラによっては、" "で囲まれたヘッダファイルの探索ディレクトリを追加する手段を別途用意しているものもあります。
トラックバック
ブックナビゲーション
- 技術情報
- Boost C++ Libraries メモ
- C++と組込み環境
- C++サンプル集
- C++テンプレート集
- C++プログラマのためのC言語入門
- C/C++迷信集
- [迷信] 'A'~'Z' の値は連続している
- [迷信] 0xe-0xe はゼロ
- [迷信] 1 バイトは 8 ビット
- [迷信] 2の累乗による割り算と右シフトは等価
- [迷信] FILE 型は構造体
- [迷信] abs は常に非負の値を返す
- [迷信] argv[0] はプログラム名
- [迷信] char 型は符号付き
- [迷信] double の出力書式は "%lf"
- [迷信] fflush で入力バッファをクリア
- [迷信] free でメモリを開放する
- [迷信] free に NULL を渡すとクラッシュする
- [迷信] gets は単純に fgets に置き換えられる
- [迷信] isalpha 関数の引数は char 型
- [迷信] new に失敗すると NULL が返る。
- [迷信] scanf ではバッファオーバーランを防げない
- [迷信] scanf でキーボードから入力
- [迷信] setjmp マクロの返却値は変数に代入できる
- [迷信] sizeof は定数式
- [迷信] void main(void)
- [迷信] とりあえず memset で初期化
- [迷信] アルゴリズム関数内で関数オブジェクトはコピーされない
- [迷信] オブジェクトの動的生成に失敗するとメモリリークする
- [迷信] コンストラクタから例外を送出してはならない
- [迷信] コンストラクタで自身をゼロクリア
- [迷信] コンパイラはプログラマの心を察してくれる
- [迷信] コンパイルエラーが出るのでアクセス指定子を修正
- [迷信] ソースコード中の即値を全廃せよ
- [迷信] ソースファイルの末尾に }
- [迷信] データ列のソートには qsort 関数を使うべし
- [迷信] プログラムは必ず main から始まる
- [迷信] 一重引用符の中には一文字しか書けない
- [迷信] 今どき int が 16 ビットの処理系なんて無い
- [迷信] 入力データ格納用配列のサイズは BUFSIZ
- [迷信] 割付けたメモリはプログラマが自分で解放しなければならない
- [迷信] 実数型とは浮動小数点型のことである
- [迷信] 引用符で囲んだヘッダ名はカレントディレクトリから探索する
- [迷信] 文字列から整数への変換には atoi
- [迷信] 構造体のタグ名は下線で始める
- [迷信] 構造体はクラスではない
- [迷信] 識別子に使える文字は英数字と下線のみ
- [迷信] 非局所オブジェクトは外部結合
- C言語再入門
- C言語徹底入門
- Drupal メモ
- TOPPERS 情報
- ライブラリ開発入門
- 分割コンパイルをきわめる
- 擬似プロセッサを作る
- 車輪の再発明
- 過去の情報

