c言語 ヘッダ整理 extern宣言とprototype宣言の重複防止

c言語のソースファイルとヘッダファイルにおいて、
インクルード時にextern宣言とprototype宣言の重複防止しながらもカッチョよくスッキリサッパリ整理する方法についてお知恵を拝借したく。

ファイル構成としては現状こんな感じです。

main.c <== 関数 main() から各関数をCallする。
xx01.c <== 関数 xx01_func1()、xx01_func2()…の実体とprototype宣言
xx01.h <== 上記のextern宣言
xx02.c <== 関数 xx02_func1()、xx02_func2()…の実体とprototype宣言
xx02.h <== 上記のextern宣言
 :
 :

考え方としては、以下3点
1)グローバルに参照したいもの(extern宣言)はhにまとめて、みんなでインクルードする
2)ユニークであるべきもの(prototype宣言)は実体と共にある
3)extern宣言とprototype宣言は重複しないようにすべし

ここで、3)を実現する方法について、悩んでおります。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2015/08/22 00:16:26
id:gm91

質問者から

GM912015/08/21 05:57:02

==補足==

//xx01.h の内容は以下の通り。

#ifndef _X01_EXT

#define _X01_EXT

extern void xx01_func1(void); /* 実体とプロトタイプ宣言は xx01.c に記載 */

extern void xx01_func2(void); /* 実体とプロトタイプ宣言は xx01.c に記載 */

extern void xx01_func3(void); /* 実体とプロトタイプ宣言は xx01.c に記載 */

extern void xx01_func4(void); /* 実体とプロトタイプ宣言は xx01.c に記載 */

#endif

=====

//xx02.h の内容は以下の通り。

#ifndef _X02_EXT

#define _X02_EXT

extern void xx02_func1(void); /* 実体とプロトタイプ宣言は xx02.c に記載 */

extern void xx02_func2(void); /* 実体とプロトタイプ宣言は xx02.c に記載 */

extern void xx02_func3(void); /* 実体とプロトタイプ宣言は xx02.c に記載 */

extern void xx02_func4(void); /* 実体とプロトタイプ宣言は xx02.c に記載 */

#endif

: 以下 xx75.hまで 同様。

ここで、各々の .cファイルから、すべての.hファイルをインクルードしようとすると

#include "xx01.h"

#include "xx02.h"

:

:

#include "xx75.h"

となるが、この部分を更に allinc.h というヘッダファイルにしてしまって

各 .cファイルからは、冒頭で

#include "allinc.h"

としてしまえば楽ちんかな、と思った。

ですが、この場合、例えば 

xx01.c 内で定義している関数のprototypeが、インクルードしたextern宣言と重複してしまうことになります。

#ifndef をうまく使って 実体を定義したファイルに限っては重複するexternを無効にするようにできるのではないかと思うのですが、詳しい方教えていただけないでしょうか。

もしくは、そもそもそんな構造にしなくても、こうすればいいよ的なご提案でもOKです。

うまくやれば、extern宣言とprototype宣言を一つのhにまとめたりできるのでは?

とかも考えてみたりしてますが、ちょっと混乱してきた… <(*_*<

何卒宜しくお願い致します。

ベストアンサー

id:pogpi No.1

回答回数428ベストアンサー獲得回数59

#define _X01_EXT

を、xx01.cファイルの

#include "allinc.h"

の前に書くのは、どうですか。2以降も同様に。

id:gm91

最初考えていたのはそういうイメージでした。ありがとうございました。

2015/08/22 00:12:40

その他の回答1件)

id:pogpi No.1

回答回数428ベストアンサー獲得回数59ここでベストアンサー

#define _X01_EXT

を、xx01.cファイルの

#include "allinc.h"

の前に書くのは、どうですか。2以降も同様に。

id:gm91

最初考えていたのはそういうイメージでした。ありがとうございました。

2015/08/22 00:12:40
id:JULY No.2

回答回数966ベストアンサー獲得回数247

こんな感じかなぁ。

  • xx01.h
#ifdef __XX01_C
#define _EXTERN
#else
#define _EXTERN extern
#endif

_EXTERN void xx01_func1(void);
_EXTERN void xx01_func2(void);

  • xx01.c
#define __XX01_C
#include "xx01.h"

ただ、Linux 上のヘッダファイルとかをちらっとみた感じだと、プロトタイプ宣言に extern を付けないのが普通ですね。

id:gm91

たしかに extern自体を #define 定義する手もありますね。
ありがとうございます。

2015/08/22 00:14:18
  • id:a-kuma3
    extern が付いているとプロトタイプ宣言にならない、と勘違いしてません?

    プロトタイプ宣言は、その関数を呼び出す側のためにあるものなので、ヘッダに書きます。
    関数軍の呼び出しの後先があるので、実装しているソースでもプロトタイプ宣言が必要なこともままあるでしょう。

    ■xx01.h

    #ifndef _X01_EXT
    #define _X01_EXT

    extern int xx01_func1(const char*, int);
    extern int xx01_func2(int, double);

    #endif /* _X01_EXT */


    ■xx01.c

    #include "xx01.h"

    /* ここに、こういうふうに書くのではないです
    int xx01_func1(const char*, int);
    int xx01_func2(int, double);
    */

    int xx01_func1(const char* s, int n) {
    ...
    }

    int xx01_func2(int n, double f) {
    ...
    }


    ■main.c

    #include "xx01.h"
    #include "xx02.h" /* まとめた allinc.h でも良いんですが */

    ...


    グローバル変数の実体と extern の話と混同してませんか?

    それとも、実態を定義している *.c からプロトタイプ宣言を *.h に書き出すのがかったるいとかいう話でしょうか?
  • id:gm91
    あ、なんか勘違いしてたかも、です。

    確認の為、ちょっと質問を単純化すると
    例えば

    hogehoge.c
    hogehoge.h

    だけのファイル構成だとして
    ■hogehoge.c
    #include "hogehoge,h"

    int hoge(char a){
    ~~~~
    }

    ■hogehoge.h

    extern int hoge(char);

    こんな感じでOKってことですか?
  • id:a-kuma3
    >こんな感じでOKってことですか?
    そうです。
    であれば、重複、という感じにはならないですよね。
  • id:gm91
    ありがとうございます。
    すっきりしました。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません