分割コンパイルについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
イマダニ

分割コンパイルについて

#1

投稿記事 by イマダニ » 7年前

分割コンパイルではよく別ファイルで定義したものをまた別のファイルで呼び出すことがありますよね。
たとえばこんな感じに
void sshot(PLAY play,SHOT shot[MAX_SHOT])
プレイヤーが弾を撃つための関数やらなにやらが書かれている、
shot.cppにあるsshot関数でプレイヤーの座標を使うためplay.hで定義した構造体を呼び出したりとかありますよね。
この時、shot.hに

コード:

#ifndef DEF_SHOT_H
#define DEF_SHOT_H
#define MAX_SHOT 100
typedef struct{
	int img;
	double x,y;
	bool flag;
	int sound;
}SHOT;
void sini(SHOT shot[MAX_SHOT]);
void sshot(PLAY play,SHOT shot[MAX_SHOT]);
void sgraph(SHOT shot[MAX_SHOT]);
#endif
こう書きます。すると、

error C2065: 'PLAY' : 定義されていない識別子です。
error C2146: 構文エラー : ')' が、識別子 'play' の前に必要です。

というたくさんのエラーが出ます。
ここで私は「ああ、ヘッダファイルにもplayerの構造体が定義されてるplayer.hをインクルードしなきゃならないのか」と思い、こう書きました。

コード:

#include "player.h"
#ifndef DEF_SHOT_H
#define DEF_SHOT_H
#define MAX_SHOT 100
typedef struct{
	int img;
	double x,y;
	bool flag;
	int sound;
}SHOT;
void sini(SHOT shot[MAX_SHOT]);
void sshot(PLAY play,SHOT shot[MAX_SHOT]);
void sgraph(SHOT shot[MAX_SHOT]);
#endif
するとエラーが出ず、無事作動しました。
ですが、本当にこういう書き方でいいのでしょうか?
アドバイスお願いします。

アバター
ibrn
記事: 1
登録日時: 8年前

Re: 分割コンパイルについて

#2

投稿記事 by ibrn » 7年前

基本的にはそれで問題ないと思います(play.hにPLAYがきちんと定義されていれば。)
ただ、#include "player.h"はインクルードガード(#ifdef DEF_SHOT_H ,#define DEF_SHOT_H)の後に書くよう
習慣づけることをオススメします。

beatle
記事: 1280
登録日時: 8年前
住所: 埼玉
連絡を取る:

Re: 分割コンパイルについて

#3

投稿記事 by beatle » 7年前

ibrnさんの仰るとおり、基本的には問題ありません。

今は問題にぶち当たっていないようですが、そういうパターンで#includeしてよく出会う問題として、
player.hの中でSHOT構造体を使っており、どっちを先に#includeするかを決められない(どっちにしてもエラーがでる)
というものがあります。
こういう時は、構造体の前方宣言を行います。

player.hを#includeせずに

コード:

struct PLAY_st;
typedef PLAY_st PLAY;
のようにすることで解決できます。

この場合、対応する.cファイルの方でplayer.hを#includeする必要があります。
しないと、不完全型(incomplete type)にアクセスしようとしている、という警告が出るでしょう。

イマダニ

Re: 分割コンパイルについて

#4

投稿記事 by イマダニ » 7年前

なるほど勉強になります。不安が解消されました。
ibrnさん、beatleさんこんな些細な質問にわざわざ答えてくださり
ありがとうございました!

閉鎖

“C言語何でも質問掲示板” へ戻る