C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 53 を表示中)
■29549 / )  多重インクルード防止について
□投稿者/ Cの疑問 (1回)-(2008/12/10(Wed) 16:11:19)

分類:[C/C++] 

Cの多重インクルードの防止に関して質問させてもらいたいのですが、
#include は指定ファイルをそこを展開するものだと認識しています。
その前提で、もし多重インクルード防止のため、

#ifndef _INC_HEADER_
#define _INC_HEADER_
<いろいろな定義>
#endif

として、A.c と B.c でそのヘッダをインクルードしたとします。

[質問@]
各ソースがコンパイルされる際、
例えば A.c が先にコンパイルされるとして、
_INC_HEADER_ が #define されます。

その後、B.c は既に _INC_HEADER_ が #define されていることを知っているのでしょうか?
それはどのようにして知るのでしょうか?
もし、#define されていることを知らないのであれば、
ヘッダ内の定義が、両ソースにて展開されてしまうのではないか?と思います。

[質問A]
また、#define されたことを知っているとしたならば、
B.c は #ifndef により、ヘッダ内の定義が無視されることになると思いますが、
B.c 内でヘッダに定義されている"何か"を使用しようとした場合、
認識できるのでしょうか?
コンパイルエラーになりそうな気がしてしまうのですが・・・
(定義が見つからない)

[質問B]
上記の質問内容と交えて混乱してしまっているのですが、
コンパイルオプション(/P)にて、プリプロセッサの前処理済みファイル(.i)を出力するようにしました。
結果、A.c にも B.c にも #ifndef されているにもかかわらず、
ヘッダの定義内容が展開されていました。
定義が複数箇所に散らばっていることでコンパイルエラーにはならない?
定義の重複はリンク時に判定される?

[質問C]
これらを検証するために、
最初に、ヘッダに構造体、extern無し変数、#defineマクロを
定義し、"多重インクルード防止無し"で、A.c と B.c からインクルードしてコンパイルしました。
(もちろん、#pragma once も無し)
質問Bで記した通り、A.i と B.i の両方、定義が展開されました。
少なくとも、構造体やマクロが多重定義されている旨のコンパイルエラーが出るかと思ったら、
出ませんでした。
とても不思議です・・・
どのような場合に定義の重複エラーと見なされるのでしょうか?
そもそも、私の検証内容自体に問題があるために、
上記の疑問が出てきているだけなのでしょうか?

環境は、XP・VC2008 Express です。

よろしくお願いします。


返信 編集キー/


管理者用

- Child Tree -