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