初歩的な質問ですいませんが
分割コンパイルの時、双方のファイルで同じ構造体をを使いたい場合は、どうすれば良いでしょうか?
別名で同じ要素の構造体を宣言して使うしかないのでしょうか?
分割コンパイル時の構造体宣言
Re: 分割コンパイル時の構造体宣言
多重インクルードガード付きのヘッダーファイルを作成するのがよさそうです。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
Re: 分割コンパイル時の構造体宣言
boxさま
多重インクルードガードは、誤ったインクルードで、グローバル変数などの二重定義を防ぐ機能だとおもいますが、
今回、a.cppとb.cppの両ファイルでグローバルな構造体変数を使えないかと思っています。
a.cppで定義 b.cppでcurrent[]を使いたい場合、一般の変数の場合、externで宣言すればコンパイルは通ると思いますが構造体の場合は
extern setdata current[] だとタイプ名が不明とのエラー
struct setdata{ ・・・ を書くとstructの二重定義のエラーになると思います。
このような場合、どのようにすればよいでしょうか?
多重インクルードガードは、誤ったインクルードで、グローバル変数などの二重定義を防ぐ機能だとおもいますが、
今回、a.cppとb.cppの両ファイルでグローバルな構造体変数を使えないかと思っています。
a.cppで定義 b.cppでcurrent[]を使いたい場合、一般の変数の場合、externで宣言すればコンパイルは通ると思いますが構造体の場合は
extern setdata current[] だとタイプ名が不明とのエラー
struct setdata{ ・・・ を書くとstructの二重定義のエラーになると思います。
このような場合、どのようにすればよいでしょうか?
Re: 分割コンパイル時の構造体宣言
そのような場合,通常はヘッダファイルを使います。taku_s さんが書きました:分割コンパイルの時、双方のファイルで同じ構造体をを使いたい場合は、どうすれば良いでしょうか?
例えば,こんな感じで。
setdata.h
#ifndef SETDATA_H_
#define SETDATA_H_
// 構造体の定義なので,インクルードガードが必要。
struct setdata{
int value;
int pos;
};
#endif
Re: 分割コンパイル時の構造体宣言
boxさま、Yuoさま
ありがとうございました。無事にコンパイルできました。
ただ、未だにうまく理解できません。(^^;
#ifndef SETDATA_H_
#define SETDATA_H_ で一度だけ展開すると言うことは、
a.cppに構造体の宣言が展開され、b.cppには何も展開されないように思ってしまいます。
実際にはどうなのか、展開後のソースは見れないので、ここが上手く理解できますん。
また。私の理解では
g++ -c b.cpp a.cpp とやった場合は、
b.cpp側に構造体宣言が展開され、a.cppには何も展開されずエラーになりそうな気がします。
試してみたら、実際にはエラーにならないんですね。
ここの部分が、理解できません。
ありがとうございました。無事にコンパイルできました。
ただ、未だにうまく理解できません。(^^;
#ifndef SETDATA_H_
#define SETDATA_H_ で一度だけ展開すると言うことは、
a.cppに構造体の宣言が展開され、b.cppには何も展開されないように思ってしまいます。
実際にはどうなのか、展開後のソースは見れないので、ここが上手く理解できますん。
また。私の理解では
g++ -c b.cpp a.cpp とやった場合は、
b.cpp側に構造体宣言が展開され、a.cppには何も展開されずエラーになりそうな気がします。
試してみたら、実際にはエラーにならないんですね。
ここの部分が、理解できません。
Re: 分割コンパイル時の構造体宣言
#defineによって定義されたシンボルは,コンパイルするソースファイルひとつの単位でのみ有効です。
コンパイラの引数に複数のソースファイルを書いても,基本的にコンパイラは個々にコンパイルを行います。
このため,#defineの定義は同時にコンパイラに渡された他のソースファイルの影響を受けません。
インクルードガードは,1つのソースファイルから,同一のファイルが(直接・間接問わず)複数回インクルードされた場合にエラーにならないようにする物です。
極端な例だとですが,こういうことはまず起こりません。
実際にあるのは
この場合,a.cppという1つのソースファイルからb.hが2回インクルードされることになります。
このような場合にエラーにならないように,インクルードガードを行います。
コンパイラの引数に複数のソースファイルを書いても,基本的にコンパイラは個々にコンパイルを行います。
このため,#defineの定義は同時にコンパイラに渡された他のソースファイルの影響を受けません。
インクルードガードは,1つのソースファイルから,同一のファイルが(直接・間接問わず)複数回インクルードされた場合にエラーにならないようにする物です。
極端な例だとですが,こういうことはまず起こりません。
実際にあるのは
- a.cppはb.hとc.hをインクルード
- c.hはb.hをインクルード
この場合,a.cppという1つのソースファイルからb.hが2回インクルードされることになります。
このような場合にエラーにならないように,インクルードガードを行います。
Re: 分割コンパイル時の構造体宣言
Yuoさま
丁寧に対応して頂いてありがとうございました。
もともと、私の
「struct setdata{ ・・・ を書くとstructの二重定義のエラーになると思います。」 これが間違いだったんですね。
この思い込みがあったのでなかなか理解できませんでした。
ありがとうございました。
丁寧に対応して頂いてありがとうございました。
もともと、私の
「struct setdata{ ・・・ を書くとstructの二重定義のエラーになると思います。」 これが間違いだったんですね。
この思い込みがあったのでなかなか理解できませんでした。
ありがとうございました。