分割コンパイル時の構造体宣言

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
taku_s
記事: 9
登録日時: 2年前

分割コンパイル時の構造体宣言

#1

投稿記事 by taku_s » 7ヶ月前

初歩的な質問ですいませんが
分割コンパイルの時、双方のファイルで同じ構造体をを使いたい場合は、どうすれば良いでしょうか?

別名で同じ要素の構造体を宣言して使うしかないのでしょうか?

box
記事: 1695
登録日時: 7年前

Re: 分割コンパイル時の構造体宣言

#2

投稿記事 by box » 7ヶ月前

多重インクルードガード付きのヘッダーファイルを作成するのがよさそうです。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

taku_s
記事: 9
登録日時: 2年前

Re: 分割コンパイル時の構造体宣言

#3

投稿記事 by taku_s » 7ヶ月前

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の二重定義のエラーになると思います。

このような場合、どのようにすればよいでしょうか?

YuO
記事: 911
登録日時: 7年前
住所: 東京都世田谷区

Re: 分割コンパイル時の構造体宣言

#4

投稿記事 by YuO » 7ヶ月前

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[];

taku_s
記事: 9
登録日時: 2年前

Re: 分割コンパイル時の構造体宣言

#5

投稿記事 by taku_s » 7ヶ月前

boxさま、Yuoさま
ありがとうございました。無事にコンパイルできました。
ただ、未だにうまく理解できません。(^^;

#ifndef SETDATA_H_
#define SETDATA_H_ で一度だけ展開すると言うことは、
a.cppに構造体の宣言が展開され、b.cppには何も展開されないように思ってしまいます。
実際にはどうなのか、展開後のソースは見れないので、ここが上手く理解できますん。

また。私の理解では
g++ -c b.cpp a.cpp とやった場合は、
b.cpp側に構造体宣言が展開され、a.cppには何も展開されずエラーになりそうな気がします。
試してみたら、実際にはエラーにならないんですね。

ここの部分が、理解できません。

YuO
記事: 911
登録日時: 7年前
住所: 東京都世田谷区

Re: 分割コンパイル時の構造体宣言

#6

投稿記事 by YuO » 7ヶ月前

#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回インクルードされることになります。
このような場合にエラーにならないように,インクルードガードを行います。

taku_s
記事: 9
登録日時: 2年前

Re: 分割コンパイル時の構造体宣言

#7

投稿記事 by taku_s » 7ヶ月前

Yuoさま
丁寧に対応して頂いてありがとうございました。
もともと、私の
「struct setdata{ ・・・ を書くとstructの二重定義のエラーになると思います。」 これが間違いだったんですね。
この思い込みがあったのでなかなか理解できませんでした。

ありがとうございました。

返信

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