
こんにちは。
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
このような事態に陥った場合の解決方法はどのようにすればよいでしょうか?
先輩から引き継いだ、もともと一つのソースファイルに書かれていた多数の関数を、利便性のために分割したところこのようなエラーが発生しました。
先輩から引き継いだもののため、本当の関数名など細かいことをこちらに書き込めないのですが、
出来る範囲で補足いたします。
どうかよろしくお願いいたします。
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");
}
お手数をおかけしてすみません。
自分で試せばすぐできることなのに頭が回りませんでした(汗)
ソースコードまでご丁寧に書いてくださりありがとうございました。
回答いただいたプログラムではエラーもなく正常に動作しました。
なので、今エラーが出ているプログラムは何か見落としているダメな箇所があるはずだとわかりました。
何度も見返したつもりですが、もう一度戻ってみてみることにします。
回答本当にありがとうございました。
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言語では同じシンボルを
もつ関数や変数は認められません。
回答ありがとうございます。
追加で質問させていただきたいのですが、
以下のような場合でソースファイルを分割したい場合どうすればいいのでしょうか?
・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にインクルードするというやり方をとって失敗してしまったのです。
私の理解不足で申し訳ありませんが、
もしお時間がありましたら、回答いただけるとうれしいです。
No.4
- 回答日時:
#3です。
訂正。>C++だと、同じ関数名でも、引数リストが同じであれば
C++だと、同じ関数名でも、引数リストが異なれば
回答ありがとうございます。
どうやらC++にすると平気なようなのですが、
コンパイルしてみたところ、
C++では禁止(?)のnewという名前の変数を多用しているので、
エラーが出てしまいました。
ただ、問題としているエラーは出なかったので、
その変数名を直せば行けるのでは、、、と感じます。
C++を勉強したことが無いので不安ですが、
試してみたいと思います。
また、prpgram1と2で同じものを定義しているとのことですが、
1ではtest()については定義していません。
使用はしています。
2にtest()の中身が書いてあり、
プロトタイプ宣言をしているheader.hを両方のプログラムがインクルードしています。
もし勘違いがあればすみません。
No.3
- 回答日時:
見たまんまだと思うんだけど…。
program1.cとprogram2.cで、
同じ関数testを定義しているんじゃないでしょうか。
C++だと、同じ関数名でも、引数リストが同じであれば
多重定義が可能ですが、Cではできない(であってます?)と思います。
例えば、program1,2,3のファイル名の拡張子を
.cppにしてコンパイルしたらどうなるでしょうか?
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 で書いたほうが良いのですが。
回答ありがとうございます。
やってみましたが、同じエラー内容が出ました。。。
一つ一つのコンパイルは成功しましたが、
最後の合体でエラーが出てしまいました。。。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
multiple definitionというエラー
C言語・C++・C#
-
2重定義って??
C言語・C++・C#
-
関数の実体定義にヘッダファイルの2重定義防止方法が効かない?
C言語・C++・C#
-
-
4
コンパイルエラーについて
C言語・C++・C#
-
5
main.c:7:43: warning: implicit declaration of func
C言語・C++・C#
-
6
C言語での引数の省略方法
C言語・C++・C#
-
7
C言語のコンパイルエラー
C言語・C++・C#
-
8
C言語のポインターに関する警告
C言語・C++・C#
-
9
C言語でヘッダファイルにグローバル変数を宣言する
C言語・C++・C#
-
10
fopenで別ディレクトリにファイルをオープンしたい
C言語・C++・C#
-
11
エラーの意味は? Lvalue required
C言語・C++・C#
-
12
構造体のメンバをfor文で回したい
C言語・C++・C#
-
13
C言語初心者の質問失礼します。
C言語・C++・C#
-
14
実行ファイルのパスを取得したい
C言語・C++・C#
-
15
PCC-S-02201エラーの対処を教えてください!
Oracle
-
16
<unistd.h>をVisualStudioでつかえるようにする
C言語・C++・C#
-
17
gcc バージョン違いによるコンパイルエラー
C言語・C++・C#
-
18
c++のvirtual関数および継承について
C言語・C++・C#
-
19
構造体のextern方法
C言語・C++・C#
-
20
HEWを使用しているのですが、このようなエラーが出ました。
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
既定のコンストラクタがありま...
-
C言語 ① 5秒間 1秒間隔で点滅を...
-
【gcc・cygwin】multiple defin...
-
const_castのつかいどころを教...
-
(void)0 はどんな意味ですか
-
[Visual C++ 6.0] コンパイル(...
-
C#を勉強中でC#で壁紙を変更す...
-
C++でオーバーロードに関するバ...
-
Enterキーを押されたら次の処理...
-
Aの値からBの値を除するとは??
-
「Aに対するBの割合」と「Aに対...
-
C言語での引数の省略方法
-
ある商品のロス率を5%見込み、...
-
【C言語】全角文字の配列を、全...
-
エクセルで可視セルにのみ値貼...
-
fgetsなどのときのstdinのバッ...
-
#define _CRT_SECURE_NO_WARNIN...
-
マイナスからプラスへ転じた時...
-
20'(角度)の計算がわかりま...
-
有効数字について 以前質問をし...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
静的でないメンバ関数の呼び出...
-
既定のコンストラクタがありま...
-
C++にてtemplateで受け取った任...
-
多重定義が起きている?--lnk20...
-
【gcc・cygwin】multiple defin...
-
const_castのつかいどころを教...
-
戻り値を返す関数の前に(void)...
-
C言語 ① 5秒間 1秒間隔で点滅を...
-
C# Controls.Addで動的に配置し...
-
C#でテンキーの操作は可能でし...
-
int main()、void main()、void...
-
C# KeyDownイベントでショート...
-
gcc: incompatible pointer type
-
Notepad++の関数リスト表示の変...
-
(void)0 はどんな意味ですか
-
VC++でGetKeyboardStateがうま...
-
関数ポインタについて
-
void main()って誰が最初?:AN...
-
演算子のオーバーロードでコン...
-
この式の意味
おすすめ情報