• ベストアンサー

条件付き取り込み

C のヘッダーファイルでは、条件付き取り込みとして、 #ifndef SAMPLE #define SAMPLE /* sample.hの内容をここに書く */ #endif のように書くのが定石のようですが、これが無いと、具体的にどういう場合に不具合が出るのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.2

やってみればわかりますけどね…。 標準のヘッダを書き換えるわけにはいかないでしょうから、下記のような方法とか。 # 環境依存するかも知れない。とりあえずVC++2010ExpressEditionで確認。 間にあるundefをコメントアウトしてみたりしてコンパイルしてみるといいでしょう。 #include <stdio.h> #undef _INC_STDIO #include <stdio.h> int main(int argc, char *aargv[]) {  return 0; } >これが無いと、具体的にどういう場合に不具合が出るのでしょうか。 複数のファイルでincludeしている時にハマることがあります。 header1.hで #include "sample.h" していて、 header2.hでも #include "sample.h" していて、 source.cで #include "header1.h" #include "header2.h" していた…とか。 構造体や定数定義とかが複数のファイルにまたがっていたりするといろいろインクルードすることになって、同じファイルが複数回インクルードされることになる。とかいう事態が発生する場合があります。 そんな時に威力を発揮しますね。

ahkrkr
質問者

お礼

回答ありがとうございます。 確かに、ヘッダーファイルの中でヘッダーファイルをインクルードするとそういうことが起こるかもしれませんね。

その他の回答 (2)

回答No.3

Cでは「1回しか定義できないもの」や「1回しか宣言しちゃいけないもの」があります。 そして「あるヘッダーから、別のヘッダーを呼び出している」って事もあります。 例えば、stdio.hの中では、stdio.hで必要な標準の定義を、_stddef.hを呼び出して行っています。 ユーザーが、以下のように書いたら、どうなるでしょう? #include <_stddef.h> #include <stdio.h> こう書くと、_stddef.hは「1つのソースファイルで、2回呼び出される」ことになります。 ユーザーは「stdio.hの中でも呼んでるとは思ってない」ですから「_stddef.hが2回呼ばれているとは思ってない」です。 もし、_stddef.hの中に「1回しか定義できないもの」や「1回しか宣言しちゃいけないもの」があったら、どうなるでしょう? 当然「2回呼び出した段階で、コンパイルエラー」です。 ですが、質問文にあるように「条件付き取り込み」をやっておけば「2回呼び出されたら、2回目は何もしない」ので、コンパイルエラーにはなりません。 もし「ヘッダーファイルの中では、入れ子でヘッダーファイルを呼び出さない」って決めれば、こういう事が起きません。ユーザーが「明示的に2回呼び出さない限りは、2回は呼び出されない」ですから。 しかし「ヘッダーの中に、別のヘッダーを呼び出すのように書いてはいけない」とすると、もっと困った事になります。 stdio.hは_stddef.hに依存します。_stddef.hは_defs.hに依存します。 ユーザーが #include <stdio.h> と書くと、事前に_stddef.hを呼び出してないので、コンパイルエラーになります。 未定義エラーが出て、それが何処で定義されているか調べないと「事前に_stddef.hが呼び出されていないといけない」って事が判りません。 じゃあ、って言って #include <_stddef.h> #include <stdio.h> って書くと、今度は、事前に_defs.hを呼び出してないので、コンパイルエラーになります。 そして #include <_defs.h> #include <_stddef.h> #include <stdio.h> って書いて、やっとコンパイルに成功します。 これでは面倒なので「stdio.hの中で、自動的に_stddef.hを呼び出す」、「_stddef.hの中で、自動的に_defs.hを呼び出す」って言うようにしたのです。 そうすれば #include <stdio.h> って書くだけで済みますから。 もちろん、これらは、ユーザーが #include <_defs.h> #include <_stddef.h> #include <stdio.h> と書いても「2重定義エラー」にならないよう、条件付き取り込みで、2回以上取り込んでも問題無いようになっています。 このように「2重取り込みされても問題ないように書く」のです。

ahkrkr
質問者

お礼

よく分かりました。 ありがとうございました。

  • maiko0318
  • ベストアンサー率21% (1483/6969)
回答No.1

二重三重の定義でエラーになりますね。 内容は同じでも、コンパイラーには重複しているように見えますから。

関連するQ&A

専門家に質問してみよう