C言語関係掲示板

過去ログ

No793 #ifndef〜#defineによる二重読み込み防止について

[戻る] [ホームページ]
No.9899

#ifndef〜#defineによる二重読み込み防止について
投稿者---SHINTAKA(2003/10/20 11:02:52)


はじめて書き込みます、SINTAKAと申します。
4年程Javaでプログラミングを行っていましたが、最近C/C++に興味を持ち、
色々と勉強をしているところです。

さて、ヘッダファイルを二重読み込み防止するために、ヘッダファイル
全体を#ifndef 〜 #endifで囲う手法(以下include guardと呼びますね)
があるかと思いますが、うまく機能していないことに気付きました。
例えば、以下に示す3つのファイルはリンカにglobalFunc()の多重定義が
あるというエラーによりリンクしてもらえません。
include guradeの使い方を勘違いしているのだと思いますが、どこを
勘違いしているか、ご教授いただけないでしょうか?

コンパイラ環境は、UNIX(solaris)のSUN WorkShopとGNU C(gcc)
です。

----GlobalFunc.h----
/*
  globalFunc()を定義・実装しているヘッダファイル。
*/
#ifndef _GlobalFunc_h_
#define _GlobalFunc_h_

void globalFunc(){}

#endif
----EOF----

----UseGlobalFunc.c----
/*
  globalFunc()を利用するファイル。ここではinclude一行。
*/
#include "GlobalFunc.h"
----EOF----
----Main.c----
/*
  globalFunc()を利用する二つ目のファイル。
  2回目の #include "GlobalFunc.h"は読まれないはずだが?
*/
#include "GlobalFunc.h"
main() {}
----EOF----




No.9901

Re:#ifndef〜#defineによる二重読み込み防止について
投稿者---YuO(2003/10/20 11:10:14)


>さて、ヘッダファイルを二重読み込み防止するために、ヘッダファイル
>全体を#ifndef 〜 #endifで囲う手法(以下include guardと呼びますね)
>があるかと思いますが、うまく機能していないことに気付きました。
>例えば、以下に示す3つのファイルはリンカにglobalFunc()の多重定義が
>あるというエラーによりリンクしてもらえません。
>include guradeの使い方を勘違いしているのだと思いますが、どこを
>勘違いしているか、ご教授いただけないでしょうか?

include guardは,一つの翻訳単位においてのみ有効です。
関数の実装とか変数の定義をヘッダファイルで行ってはいけません。


No.9903

Re:#ifndef〜#defineによる二重読み込み防止について
投稿者---SHINTAKA(2003/10/20 11:20:13)


早速のお返事、どうもありがとうございます。

>include guardは,一つの翻訳単位においてのみ有効です。
>関数の実装とか変数の定義をヘッダファイルで行ってはいけません。

そうでしたか! 勉強になりました、ありがとうございました。
発端は、C++でoperator>>のオーバーロードのためだけに.cppファイル
を作成する必要が起きたのですが、ほんの数行なので.hに入れられれば、、
と思いヘッダファイルに実装を書いてしまいました。専用の.cppを
作ろうと思います。

どうもありがとうございました。


No.9902

Re:#ifndef〜#defineによる二重読み込み防止について
投稿者---たいちう(2003/10/20 11:16:01)


> globalFunc()を利用する二つ目のファイル。
> 2回目の #include "GlobalFunc.h"は読まれないはずだが?

コンパイルの単位はソースファイルごとですので、
Main.cにとってもGlobalFunc.hをインクルードするのは1回目です。

// b.h
#include "a.h"

// c.h
#include "b.h"

// main.c
#include "b.h"
#include "c.h"

このような場合に、main.cをコンパイルするときに、a.hにinclude guard
が必要になります。

SHINTAKAさんの場合の解決方法としては、globalFunc()の宣言をGlobalFunc.hに、
定義をGlobalFunc.cに書くこと等でしょうか。

No.9911

Re:#ifndef〜#defineによる二重読み込み防止について
投稿者---SHINTAKA(2003/10/20 11:51:48)


SHINTAKAです。

>コンパイルの単位はソースファイルごとですので、
>Main.cにとってもGlobalFunc.hをインクルードするのは1回目です。

>SHINTAKAさんの場合の解決方法としては、globalFunc()の宣言をGlobalFunc.hに、
>定義をGlobalFunc.cに書くこと等でしょうか。

どうも、お返事ありがとうございます。「コンパイル単位」を
勘違いしておりました。include guardの利用方法も理解でき、
とてもすっきり致しました。