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

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

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

Re[4]: 多重インクルード防止について


(過去ログ 53 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■29549 / inTopicNo.1)  多重インクルード防止について
  
□投稿者/ 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 です。

よろしくお願いします。


引用返信 編集キー/
■29550 / inTopicNo.2)  Re[1]: 多重インクルード防止について
□投稿者/ .SHO (366回)-(2008/12/10(Wed) 16:18:11)
No29549 (Cの疑問 さん) に返信

> [質問@]
> その後、B.c は既に _INC_HEADER_ が #define されていることを知っているのでしょうか?

知りません。

> ヘッダ内の定義が、両ソースにて展開されてしまうのではないか?と思います。

両ソースに展開されても問題ありません。
それよりも、関数のプロトタイプなどは、両ソースに展開されなければ意味がありません。

> [質問A]
> また、#define されたことを知っているとしたならば

知らないのでこの質問は除外。

> [質問B]
> 定義が複数箇所に散らばっていることでコンパイルエラーにはならない?

a.c と b.c はコンパイル時には無関係です。

> 定義の重複はリンク時に判定される?

具体的にどのようなケースで問題になる(と思われる)のでしょう?

> [質問C]
> どのような場合に定義の重複エラーと見なされるのでしょうか?

a.c (b.c) で、2回 include した時です。

> そもそも、私の検証内容自体に問題があるために、
> 上記の疑問が出てきているだけなのでしょうか?

a.c と b.c は、コンパイル時には無関係というのを理解してください。
引用返信 編集キー/
■29551 / inTopicNo.3)  Re[2]: 多重インクルード防止について
□投稿者/ Cの疑問 (3回)-(2008/12/10(Wed) 16:36:09)
No29550 (.SHO さん) に返信
ご回答有り難う御座います。

そもそも私は認識違いをしていたようです。。。

あらためてお聞きしたいのですが、
多重インクルード防止は、

「一つのヘッダが複数ソースファイルでインクルードされることが問題ではない」、
例えばネスト的にヘッダがインクルードされている場合に、
気づかず、「一つのソースファイル内で同ヘッダが多重的にインクルードされるのを防ぐ」
ものであるという認識であってますでしょうか?


引用返信 編集キー/
■29552 / inTopicNo.4)  Re[3]: 多重インクルード防止について
□投稿者/ .SHO (367回)-(2008/12/10(Wed) 16:40:42)
No29551 (Cの疑問 さん) に返信

> 「一つのヘッダが複数ソースファイルでインクルードされることが問題ではない」、
> 例えばネスト的にヘッダがインクルードされている場合に、
> 気づかず、「一つのソースファイル内で同ヘッダが多重的にインクルードされるのを防ぐ」
> ものであるという認識であってますでしょうか?

完璧です!

sub1.h で #include <stdio.h>
sub2.h で #include <stdio.h>

と定義されていて

main.c で
#include <sub1.h>
#include <sub2.h>
として stdio.h を多重インクルードするようなことは
気付かないうちに頻繁に発生しています。
引用返信 編集キー/
■29556 / inTopicNo.5)  Re[4]: 多重インクルード防止について
□投稿者/ Cの疑問 (4回)-(2008/12/10(Wed) 16:57:46)
No29552 (.SHO さん) に返信
.SHOさん、有り難う御座いました。


解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -