こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

相互に参照する構造体について

Cプログラミングについての質問です。よろしくお願いします。

以下のヘッダファイル(defx.h, defy.h)および、mainファイルが正しくコンパイルされるということなのですが、自分の環境(WinXP下でのgcc(MinGW))ではエラーが出ます。
エラー内容は
error: redefinition of typedef 'SY'
error: previous declaration of 'SY' was here
error: redefinition of typedef 'SY'
error: previous declaration of 'SY' was here
です。
<defx.h>
#if !defined(__SX)
#define __SX
typedef struct __sy SY;
typedef struct {
inta;
SY*b;
} SX;
#endif
<defy.h>
#if !defined(__SY)
#define __SY
#include "defx.h"
typedef struct __sy {
intc;
SXd;
} SY;
#endif

mainファイルについては
#include "defx.h"
#include "defy.h"

int main(void)
{
SX s;
SY t;
}
以上ですが、
よろしくお願い致します。

投稿日時 - 2009-08-04 18:54:43

QNo.5181699

困ってます

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(8)

ANo.8

> gcc はわりと柔軟なので「ヘッダファイルを与える」くらいではこけたりしません

GCCにヘッダファイルをプリコンパイルヘッダを生成してしまいます。
やって悪いとはいいませんが、ここでは不要ですし、おそらく意図した操作でもないでしょう。

そうではなく、コマンドにg++ではなくgccを使うと、main.cppはCのソースとしてコンパイルされてしまいます。
C++であれば、定義に矛盾がないかぎりtypedefは重複してもかまいませんが、Cの場合はコンパイルエラーになります。今回の問題は、まさにそこにあります。

投稿日時 - 2009-08-05 15:49:13

ANo.7

本題とは関係ありませんが, gcc はわりと柔軟なので「ヘッダファイルを与える」くらいではこけたりしません>#5&#6. 実際, 今の例でもちゃんと動きます (実験済み).
もちろん「他の処理系」のことを念頭に置くと「ヘッダファイルは与えない方がよい」のは事実ですが.

投稿日時 - 2009-08-05 15:41:18

ANo.6

>gcc main.cpp defx.h defy.h

これはダメでしょう。

g++ main.cpp

とすれば、ちゃんとコンパイルできましたよ。

投稿日時 - 2009-08-05 15:20:11

お礼

有難う御座いました。
コンパイル通りました。

C++ではコンパイルできましたが、
Cではコンパイルできないということでしょうか?
他の方の回答でCでコンパイル出来るか考えてみます。

投稿日時 - 2009-08-05 16:13:15

ANo.5

#include しているのだから、コンパイルコマンドは
>gcc main.cpp
だけでいいのではないでしょうか

投稿日時 - 2009-08-05 13:47:27

ANo.4

これでどうでしょうか
<defx.h>
#if !defined (__SX)
#define __SX
struct sy;
struct sx{
int a;
struct sy *b;
};
typedef struct sx SX;
#endif
<defy.h>
#if !defined (__SY)
#define __SY
struct sx;
struct sy {
int c;
struct sx *d;
};
typedef struct sy SY;
#endif
<main.c>
#include <stdio.h>
#include "defx.h"
#include "defy.h"
int main()
{
SX s;
SY t;
s.a=1;
s.b=&t;
t.c=-1;
t.d=&s;
printf("s.a = %d\n",s.b->d->a);
printf("t.c = %d\n",t.d->b->c);
}

投稿日時 - 2009-08-05 13:42:26

ANo.3

書き換えてダメだったときには, 「このように書き換えたんだけど」とプログラムを出すようにしてください. わざわざ秘密にして他人に当てさせる必要性なんて, 微塵もないはずだよね.
さておき, #2 の「typedef するのをやめる」というのは, 「単純に typedef を消す」という意味ではありません. 「SY に typedef するのをやめて, 構造体の宣言だけをする」という意味です.

投稿日時 - 2009-08-05 12:47:35

お礼

どうもすいませんでした。で、defy.hを以下のように修正した結果、
コンパイル通りました。

#if !defined(__SY)
#define __SY
#include "defx.h"
struct __sy {
int c;
SX d;
};
#endif

投稿日時 - 2009-08-05 16:46:38

ANo.2

defy.h で typedef するのをやめればいいとおもう.
ついでにいうと「_」ではじまる識別子はあまり使わない方がいい.

投稿日時 - 2009-08-05 01:06:33

補足

御回答有難う御座いました。

回答の通りにしてコンパイルしてみたが、
以下のエラーが出ました。

defy.h:13: error: 'SY' redeclared as different kind of symbol
defx.h:8: error: previous declaration of 'SY' was here
main.c:8: error: syntax error before "t"
defy.h:13: error: 'SY' redeclared as different kind of symbol
defx.h:8: error: previous declaration of 'SY' was here

投稿日時 - 2009-08-05 10:25:27

ANo.1

Cでコンパイルしようとしているのでは?
C++ならコンパイルできると思います。

投稿日時 - 2009-08-04 22:02:20

補足

御回答有難う御座いました。

回答の通りC++としてコンパイル
(mainファイルの拡張子を.cから.cppに変更、中身はそのまま)
してみましたが、以下のエラーが出ました。

defy.h:13: error: redefinition of typedef 'SY'
defx.h:8: error: previous declaration of 'SY' was here

なお、コンパイル方法は次の通りです。
>gcc main.cpp defx.h defy.h

投稿日時 - 2009-08-05 10:19:01

あなたにオススメの質問