• ベストアンサー

【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 このような事態に陥った場合の解決方法はどのようにすればよいでしょうか? 先輩から引き継いだ、もともと一つのソースファイルに書かれていた多数の関数を、利便性のために分割したところこのようなエラーが発生しました。 先輩から引き継いだもののため、本当の関数名など細かいことをこちらに書き込めないのですが、 出来る範囲で補足いたします。 どうかよろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • hidebun
  • ベストアンサー率50% (92/181)
回答No.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"); }

komakana
質問者

お礼

お手数をおかけしてすみません。 自分で試せばすぐできることなのに頭が回りませんでした(汗) ソースコードまでご丁寧に書いてくださりありがとうございました。 回答いただいたプログラムではエラーもなく正常に動作しました。 なので、今エラーが出ているプログラムは何か見落としているダメな箇所があるはずだとわかりました。 何度も見返したつもりですが、もう一度戻ってみてみることにします。 回答本当にありがとうございました。

その他の回答 (5)

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.5

>・エラーの文章 >(パス省略)/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言語では同じシンボルを もつ関数や変数は認められません。

komakana
質問者

お礼

回答ありがとうございます。 追加で質問させていただきたいのですが、 以下のような場合でソースファイルを分割したい場合どうすればいいのでしょうか? ・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)
回答No.4

#3です。訂正。 >C++だと、同じ関数名でも、引数リストが同じであれば C++だと、同じ関数名でも、引数リストが異なれば

komakana
質問者

お礼

回答ありがとうございます。 どうやらC++にすると平気なようなのですが、 コンパイルしてみたところ、 C++では禁止(?)のnewという名前の変数を多用しているので、 エラーが出てしまいました。 ただ、問題としているエラーは出なかったので、 その変数名を直せば行けるのでは、、、と感じます。 C++を勉強したことが無いので不安ですが、 試してみたいと思います。 また、prpgram1と2で同じものを定義しているとのことですが、 1ではtest()については定義していません。 使用はしています。 2にtest()の中身が書いてあり、 プロトタイプ宣言をしているheader.hを両方のプログラムがインクルードしています。 もし勘違いがあればすみません。

  • hidebun
  • ベストアンサー率50% (92/181)
回答No.3

見たまんまだと思うんだけど…。 program1.cとprogram2.cで、 同じ関数testを定義しているんじゃないでしょうか。 C++だと、同じ関数名でも、引数リストが同じであれば 多重定義が可能ですが、Cではできない(であってます?)と思います。 例えば、program1,2,3のファイル名の拡張子を .cppにしてコンパイルしたらどうなるでしょうか?

  • maku_x
  • ベストアンサー率44% (164/371)
回答No.2

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 で書いたほうが良いのですが。

komakana
質問者

お礼

回答ありがとうございます。 やってみましたが、同じエラー内容が出ました。。。 一つ一つのコンパイルは成功しましたが、 最後の合体でエラーが出てしまいました。。。

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.1

単純に header.h にインクルードガードがかかっていないとか?

komakana
質問者

お礼

回答ありがとうございます。 インクルードガードとは、 #ifndef _HEADER_H_ #define _HEADER_H_ ・・・ #endif のことですよね?? 上記のものならやってあります。

関連するQ&A

  • multiple definitionというエラー

    現在Ubuntu LinuxのgccでC言語のプログラムをやっています。 https://sourceforge.jp/projects/cc1101driver/scm/svn/blobs/2452/trunk/20140411/code.h このツリーのcode.hに ”const sig_code2_t PVC_TCP_SIG_CODE[100] = {” というコードを追加してmakeを行うと次のようなエラーが出て実行ファイルが出力されません。 (エラー内容) ---------------(中略)----------------- gcc -o exe main.o event.o env.o audio.o task.o comm.o menu_show_status.o mount.o net.o misc.o -lpthread event.o:(.rodata+0x0): multiple definition of `PVC_TCP_SIG_CODE' main.o:(.rodata+0x0): first defined here env.o:(.rodata+0x0): multiple definition of `PVC_TCP_SIG_CODE' main.o:(.rodata+0x0): first defined here audio.o:(.rodata+0x0): multiple definition of `PVC_TCP_SIG_CODE' main.o:(.rodata+0x0): first defined here task.o:(.rodata+0x0): multiple definition of `PVC_TCP_SIG_CODE' main.o:(.rodata+0x0): first defined here comm.o:(.rodata+0x0): multiple definition of `PVC_TCP_SIG_CODE' main.o:(.rodata+0x0): first defined here mount.o:(.rodata+0x0): multiple definition of `PVC_TCP_SIG_CODE' main.o:(.rodata+0x0): first defined here net.o:(.rodata+0x0): multiple definition of `PVC_TCP_SIG_CODE' main.o:(.rodata+0x0): first defined here misc.o:(.rodata+0x0): multiple definition of `PVC_TCP_SIG_CODE' main.o:(.rodata+0x0): first defined here collect2: error: ld returned 1 exit status make: *** [exe] Error 1 この const sig_code2_t PVC_TCP_SIG_CODE[100] = {をコメントアウト正常にビルドできるのですが、 この問題を解決するにはどうすれば良いのかご教示頂きますようお願い致します。

  • cygwinのgccが、エラーになってしまいます。

    テストプログラム $ cat test.c #include <stdio.h> int main (void) { printf("Hello, World!\n"); return 0; } これを、コンパイルすると $ gcc test.c gcc: error trying to exec '/usr/lib/gcc/i686-pc-cygwin/4.5.3/cc1.exe': execv: Bad address /usr/lib/gcc/i686-pc-cygwin/4.5.3/../../../libcygwin.a(libcmain.o):(.text+0xba): undefined reference to `_WinMain@16' collect2: ld はステータス 1 で終了しました と、このようなエラーが出てきました。 ファイルを確認しても、何も作られていません。 $ ls test.c 対処方法を、ご教示願います。

  • Cygwinのgccについて

    駄文で申し訳ありません。 cygwinのgccでC言語で作成したプログラムをコンパイルしたんですが、以下のようなコメントが返ってきました。 これはどういう意味なんでしょうか?warningなんで無視できるのでしょうか? ご教授下さい。 $gcc sample.c sample.c:60:2: warning: no newline at end of file /cygdrive/c/DOCUME^1/ユーザ名/LOCALS^1/Temp/cc6gA6nk.o:sample.c(.text+0xd7): undefined reference to _perro' collect2: ld returned 1 exit status

  • gcc使用時のエラー

    現在openCVで画像処理プログラミングを行おうとしております。 一通りコーディングが終わった所でgccを使用してコンパイルをかけた所、 下記のようなエラーが出ました。 (コード中でhighgui.h及びcv.hをインクルードしています。) /tmp/cch6hMvI.o: In function `cvDecRefData': test.c:(.text+0xaa6): undefined reference to `cvFree_' test.c:(.text+0xb2e): undefined reference to `cvFree_' これはライブラリへのパスが通っていないものと思い、端末から export LD_LIBRARY_PATH=/usr/local/lib/ としましたが、それでもエラーが出ます。さらに下記も試してみましたが同様です。 gcc -L/usr/local/lib -o test test.c (/usr/local/lib/以下にlibopencv_core.so.2.4等が置いてあります。) pkg-configを使用すればコンパイルは通るのですが、 何がどうなってエラーになっているのかイマイチ分からず気持ちが悪いです。 1、上記エラーは共有ライブラリへのパスが通っていないために起きているものですか? 2、そうだとすれば、-Lやexport LD_LIBRARY_PATHで解決出来ないのは何故でしょう? 上記だけで情報が不足している場合は提示致しますので、 どうぞよろしくお願い致します。

  • コンパイル時に見たことないエラーが出ました

    Cygwinを使ってコンパイルしたんですが ============================ /cygdrive/c/DOCUME~1/(コンパイルしたファイルのパス).c:(.text+0x187): undefi ned reference to `_(関数名)' ============================ というメッセージがでてきてコンパイルできません。 原因は何なのでしょうか?

  • CygwinでPostgreSQL makeエラー

    お世話になります。 Cygwin(ver:1.7.10-1)でPostgreSQL(ver:8.3.13)をインストールしたいのですが、make all時に以下のエラーが発生します。 Cygwinパッケージの不足等があるのでしょうか?何かアドバイスをいただけるとありがたいです。 ====================================================== rm -f thread.c && ln -s ../../../../src/port/thread.c . gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Winline -Wdeclaration-after-statement -Wendif-labels -fno-strict-aliasing -fwrapv -I../include -I../../../../src/interfaces/ecpg/include -I../../../../src/interfaces/libpq -I../../../../src/port -I../../../../src/include -DBUILDING_DLL -c -o thread.o thread.c dlltool --export-all --output-def ecpg.def execute.o typename.o descriptor.o data.o error.o prepare.o memory.o connect.o misc.o path.o pgstrcasecmp.o thread.o dllwrap -Wl,--enable-auto-import -o cygecpg.dll --dllname cygecpg.dll --def ecpg.def execute.o typename.o descriptor.o data.o error.o prepare.o memory.o connect.o misc.o path.o pgstrcasecmp.o thread.o -L../pgtypeslib -L../../../../src/interfaces/libpq -L../../../../src/port -L/usr/local/lib -lpgtypes -lpq -lm execute.o:execute.c:(.text+0x20e1): undefined reference to `_libintl_setlocale' execute.o:execute.c:(.text+0x2107): undefined reference to `_libintl_setlocale' execute.o:execute.c:(.text+0x251b): undefined reference to `_libintl_setlocale' execute.o:execute.c:(.text+0x255b): undefined reference to `_libintl_setlocale' execute.o:execute.c:(.text+0x262f): undefined reference to `_libintl_setlocale' execute.o:execute.c:(.text+0x26fb): more undefined references to `_libintl_setlocale' follow collect2: ld はステータス 1 で終了しました dllwrap: gcc exited with status 1 ../../../../src/Makefile.shlib:314: recipe for target `libecpg.a' failed make[4]: *** [libecpg.a] Error 1 make[4]: ディレクトリ `/home/nabe/postgresql-8.3.13/src/interfaces/ecpg/ecpglib' から出ます Makefile:6: recipe for target `all' failed make[3]: *** [all] Error 2 make[3]: ディレクトリ `/home/nabe/postgresql-8.3.13/src/interfaces/ecpg' から出ます Makefile:20: recipe for target `all' failed make[2]: *** [all] Error 2 make[2]: ディレクトリ `/home/nabe/postgresql-8.3.13/src/interfaces' から出ます Makefile:17: recipe for target `all' failed make[1]: *** [all] Error 2 make[1]: ディレクトリ `/home/nabe/postgresql-8.3.13/src' から出ます GNUmakefile:12: recipe for target `all' failed make: *** [all] Error 2

  • 複数のサブディレクトリを一緒にmakeして一つの実行ファイルを作成するには

    いま、Linuxの環境でC言語の勉強しています。 それで、makeを使ってコンパイル方法を調べているのですが、 ソースディレクトリとヘッダーディレクトリを分けて管理している場合に一緒にコンパイルさせる為のMakefileの書き方が分からず困っています。 現在は、同じディレクトリ内にソースファイルとヘッダーファイルが存在してます。ちなみに下記が今のMakefile内容です。 ご存知の方が記述方法もしくは参考サイトを教えて頂けますでしょうか。よろしくお願い致します。 ======================================================== program = test_pro objs = main.o test1.o test2.o CC = gcc CFLAGS = -g -Wall #suffixes_define_rule .SUFFIXES : .c .o $(program) : $(objs) $(CC) $(CFLAGS) -o $@ $^ #suffixes_rule .c.o : $(CC) $(CFLAGS) -c $< .PHONY : clean clean : $(RM) $(objs) #header_depend test1.o : test1.h test2.o : test2.h =====================================================

  • ファイル保存のパスチェック方法

    ファイル保存画面を作っています。保存先はダイアログボックスを使用せずパス付きのファイル名を入力させます。画面に入力されたファイル名(パス付)が例えば"C:\test\aaa.text"の場合"aaa.text"というファイルはまだ存在していないのでDir関数では"C:\test"が実際に存在するかどうかのチェックを行えません。何か良い方法があればお願いします。

  • cygwinのgccによるコンパイルうまくいかない

    cygwinをsetup.exeからminimum installしました。 追加的にgcc emacs xwindow system xwin terminalをインストールしました。 そしてターミナルを起動してgcc test.c -o test.exe と入力すると/home/test.c:1: error: bad value (generic) for -mtune= switch と、エラーが出てうまくコンパイル出来ません。 mtune=generic,native,i386...k6,athlon-xp..c6-2などいろいろ試しましたが全て失敗。 どうやったらコンパイルが出来るようになるか教えてください! 環境: >gcc -v >Using built-in specs. COLLECT_GCC=gcc Target: i686-pc-cygwin コンフィグオプション: /gnu/gcc/releases/respins/4.5.3-3/gcc4-4.5.3-3/src/gcc-4.5.3/configure --srcdir=/gnu/gcc/releases/respins/4.5.3-3/gcc4-4.5.3-3/src/gcc-4.5.3 --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --libexecdir=/usr/lib --datadir=/usr/share --localstatedir=/var --sysconfdir=/etc --datarootdir=/usr/share --docdir=/usr/share/doc/gcc4 -C --datadir=/usr/share --infodir=/usr/share/info --mandir=/usr/share/man -v --with-gmp=/usr --with-mpfr=/usr --enable-bootstrap --enable-version-specific-runtime-libs --libexecdir=/usr/lib --enable-static --enable-shared --enable-shared-libgcc --disable-__cxa_atexit --with-gnu-ld --with-gnu-as --with-dwarf2 --disable-sjlj-exceptions --enable-languages=ada,c,c++,fortran,java,lto,objc,obj-c++ --enable-graphite --enable-lto --enable-java-awt=gtk --disable-symvers --enable-libjava --program-suffix=-4 --enable-libgomp --enable-libssp --enable-libada --enable-threads=posix --with-arch=i686 --with-tune=generic --enable-libgcj-sublibs CC=gcc-4 CXX=g++-4 CC_FOR_TARGET=gcc-4 CXX_FOR_TARGET=g++-4 GNATMAKE_FOR_TARGET=gnatmake GNATBIND_FOR_TARGET=gnatbind --with-ecj-jar=/usr/share/java/ecj.jar スレッドモデル: posix gcc version 4.5.3 (GCC) test.cのsource #include <stdlib.h> #include <stdio.h> int main(void) { printf("Hello World!\n"); return 0; [EOF] 素人なので解決するために他に足りない情報があればおしえてくださいね。

  • プログラムが動きません。どうすれば動くのでしょうか?

    このプログラム(test.cとする)の内容を標準入力から読み込み、copied.cという名前のファイルにwモードで書き込むプログラム。(標準入力からの読み込みとファイルへの書き込みでは、1文字単位での入出力)なのですが、エラーが出て動きません。動かすにはどうすればよいでしょうか? <ソース> #include<stdio.h> int main(void) { char *filename = "copied.c"; FILE *wfp; char ch; wfp = fopen("filename", "w"); if( wfp == NULL ) { printf("ファイルが見つかりません: %s\n", filename); return 1; } while( (ch = getchar()) ) != EOF ) { fputc(ch, wfp); } fclose( wfp ); return 0; } <エラー> % gcc -o test test.c test.c: 関数 `main' 内: test.c:15: error: 文法エラー before '!=' token test.c: トップレベル: test.c:19: 警告: 関数宣言中に(型の無い)仮引数名があります test.c:19: 警告: data definition has no type or storage class test.c:20: error: 文法エラー before "return" % です。よろしくお願いします。