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)を実現する方法について、悩んでおります。
#define _X01_EXT
を、xx01.cファイルの
#include "allinc.h"
の前に書くのは、どうですか。2以降も同様に。
==補足==
//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にまとめたりできるのでは?
とかも考えてみたりしてますが、ちょっと混乱してきた… <(*_*<
何卒宜しくお願い致します。
こんな感じかなぁ。
#ifdef __XX01_C #define _EXTERN #else #define _EXTERN extern #endif _EXTERN void xx01_func1(void); _EXTERN void xx01_func2(void);
#define __XX01_C #include "xx01.h"
ただ、Linux 上のヘッダファイルとかをちらっとみた感じだと、プロトタイプ宣言に 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 に書き出すのがかったるいとかいう話でしょうか?
確認の為、ちょっと質問を単純化すると
例えば
hogehoge.c
hogehoge.h
だけのファイル構成だとして
■hogehoge.c
#include "hogehoge,h"
int hoge(char a){
~~~~
}
■hogehoge.h
extern int hoge(char);
こんな感じでOKってことですか?
そうです。
であれば、重複、という感じにはならないですよね。
すっきりしました。