- ベストアンサー
【gcc・cygwin】multiple definitionエラーの解決法
こんにちは。 C言語のプログラミングをしているのですが、 multiple definition of '関数名'と出てしまいます。 ・コンパイルするファイル program1.c(main文) program2.c(関数) program3.c(関数) すべてのソースファイルが、 header.hをincludeしています。 header.hではすべての関数のプロトタイプ宣言がされています。 program2.cに書いてある関数、test()はすべてのソースファイルで使用しています。 ・cygwin上で実行したコマンド gcc -Wall program1.c program2.c program3.c -o test ・エラーの文章 (パス省略)/ccst1v2u.o:program2.c:(.text+0x0): mult iple definition of `_test' (パス省略)/ccyUr2Ku.o:program1.c:(.text+0x0): first defi ned here このような事態に陥った場合の解決方法はどのようにすればよいでしょうか? 先輩から引き継いだ、もともと一つのソースファイルに書かれていた多数の関数を、利便性のために分割したところこのようなエラーが発生しました。 先輩から引き継いだもののため、本当の関数名など細かいことをこちらに書き込めないのですが、 出来る範囲で補足いたします。 どうかよろしくお願いいたします。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
実際にサンプルを作って確認してみましたか? 以下、インデントに全角スペースを使っています。 ソースを公開できないということなので、アドバイスできるのはここまでです。 ======= header.h ======= #ifndef _HEADER_H_ #define _HEADER_H_ #include <stdio.h> #include <stdlib.h> void test1(void); void test2(void); void test3(void); #endif ===== main.c ===== #include "header.h" int main(void) { test1(); test2(); test3(); return 0; } ===== test1.c ===== #include "header.h" void test1(void) { printf("test1() called.\n"); } ===== test2.c ===== #include "header.h" void test2(void) { test1(); printf("test2() called.\n"); } ===== test3.c ===== #include "header.h" void test3(void) { test1(); test2(); printf("test3() called.\n"); }
その他の回答 (5)
- aris-wiz
- ベストアンサー率38% (96/252)
>・エラーの文章 >(パス省略)/ccst1v2u.o:program2.c:(.text+0x0): multiple > definition of `_test' >(パス省略)/ccyUr2Ku.o:program1.c:(.text+0x0): first > defined here testがprogram2.cで多重定義されました、 testは既にprogram1.cで定義されています。 そのままですね。。。 シンボル'XXX'が多重定義されていることを意味します。 #4さんが書かれている通り、C++ではオーバロードと呼ばれる 機能を使って、同じ関数名(メソッド名)でも引数が違えば 複数定義することが可能です。しかし、C言語では同じシンボルを もつ関数や変数は認められません。
お礼
回答ありがとうございます。 追加で質問させていただきたいのですが、 以下のような場合でソースファイルを分割したい場合どうすればいいのでしょうか? ・test.c main():test1,2,3使用 test1() test2():test1使用 test3():test1,2使用 のとき、 test.cを ・main.c:mainのみ ・test1.c:test1定義 ・test2.c:test2定義 ・test3.c:test3定義 の4枚に分割したい。 私はこのような場合に、header.hというtest1,2,3がプロトタイプ宣言されているヘッダーを作り、 すべての.cにインクルードするというやり方をとって失敗してしまったのです。 私の理解不足で申し訳ありませんが、 もしお時間がありましたら、回答いただけるとうれしいです。
- hidebun
- ベストアンサー率50% (92/181)
#3です。訂正。 >C++だと、同じ関数名でも、引数リストが同じであれば C++だと、同じ関数名でも、引数リストが異なれば
お礼
回答ありがとうございます。 どうやらC++にすると平気なようなのですが、 コンパイルしてみたところ、 C++では禁止(?)のnewという名前の変数を多用しているので、 エラーが出てしまいました。 ただ、問題としているエラーは出なかったので、 その変数名を直せば行けるのでは、、、と感じます。 C++を勉強したことが無いので不安ですが、 試してみたいと思います。 また、prpgram1と2で同じものを定義しているとのことですが、 1ではtest()については定義していません。 使用はしています。 2にtest()の中身が書いてあり、 プロトタイプ宣言をしているheader.hを両方のプログラムがインクルードしています。 もし勘違いがあればすみません。
- hidebun
- ベストアンサー率50% (92/181)
見たまんまだと思うんだけど…。 program1.cとprogram2.cで、 同じ関数testを定義しているんじゃないでしょうか。 C++だと、同じ関数名でも、引数リストが同じであれば 多重定義が可能ですが、Cではできない(であってます?)と思います。 例えば、program1,2,3のファイル名の拡張子を .cppにしてコンパイルしたらどうなるでしょうか?
- maku_x
- ベストアンサー率44% (164/371)
program1.c、program2.c、program3.cそれぞれをリンクするときの組み合わせ(依存関係)が発生して、gcc が test() 関数を複数定義していると認識している気がします。試しに1つづつ分割してコンパイル gcc -Wall -c -o program1.o program1.c gcc -Wall -c -o program2.o program2.c gcc -Wall -c -o program3.o program3.c gcc -Wall -o test program1.o program2.o program3.o するとどうなりますでしょうか。 ※ 本来は Makefile で書いたほうが良いのですが。
お礼
回答ありがとうございます。 やってみましたが、同じエラー内容が出ました。。。 一つ一つのコンパイルは成功しましたが、 最後の合体でエラーが出てしまいました。。。
- koko_u_
- ベストアンサー率18% (459/2509)
単純に header.h にインクルードガードがかかっていないとか?
お礼
回答ありがとうございます。 インクルードガードとは、 #ifndef _HEADER_H_ #define _HEADER_H_ ・・・ #endif のことですよね?? 上記のものならやってあります。
お礼
お手数をおかけしてすみません。 自分で試せばすぐできることなのに頭が回りませんでした(汗) ソースコードまでご丁寧に書いてくださりありがとうございました。 回答いただいたプログラムではエラーもなく正常に動作しました。 なので、今エラーが出ているプログラムは何か見落としているダメな箇所があるはずだとわかりました。 何度も見返したつもりですが、もう一度戻ってみてみることにします。 回答本当にありがとうございました。