人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

同じ関数名で定義してもリンクでエラーになりません。

モジュールAとモジュールBがあったとします。(具体的には .a ファイルです)
両方に同じ関数名で func1 func2 func3が定義されています。
両方とも、それぞれのモジュールの中から呼び出されています。
これをビルドすると、何故かリンクエラーになりません。

試しに、モジュールBの func2をコメントアウトすると
多重定義のリンクエラーが出ます。
weak symbolは使っていません。

納得ができないのですが、説明できる方 いますでしょうか?

環境は、linuxでgccです。


●質問者: suzume_oyado
●カテゴリ:コンピュータ
✍キーワード:gcc Linux エラー コメントアウト ビルド
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● longicorn
●60ポイント

こまかい情報がないので予想で書いていきます。

a.c

//void func1(void);
void func2(void);
void func3(void);

//void func1(void){
// func2();
//}
void func2(void){
 func3();
}
void func3(void){
 func3();
}

b.c

void func1(void);
void func2(void);
void func3(void);

void func1(void){
 func2();
}
void func2(void){
 func3();
}
void func3(void){
 func3();
}
$ cat hoge.c
extern void func1(void);
extern void func2(void);
extern void func3(void);

int main(){
 func1();
 func2();
 func3();
 return 0;
}

$ gcc -c a.c b.c
$ ar rcs liba.a a.o
$ ar rcs libb.a b.o
$ gcc -Wall -o hoge hoge.c -L./ -la -lb
.//libb.a(b.o): In function `func2':
b.c:(.text+0xd): multiple definition of `func2'
.//liba.a(a.o):a.c:(.text+0x0): first defined here
.//libb.a(b.o): In function `func3':
b.c:(.text+0x1a): multiple definition of `func3'
.//liba.a(a.o):a.c:(.text+0xd): first defined here
collect2: ld はステータス 1 で終了しました

こんな感じでしょうか?


まず初めにgcc(というかld?)の動作として、同名シンボルは先優先というルールがあります。

(コンパイラ・リンカによってはこの辺のルールが違う場合もあったと記憶しています。)


よって、上記の例の場合main()->func1()と呼ばれて、リンク時はfunc1()を見にいきますがliba.aには無いのでlibb.bを見にいきます。

ここでfunc2()を探した場合、liba.aとlibb.aの両方が見つかりリンクエラーになるんだと思います。


a.cのコメントアウトを外すと、main()->func1()でliba.aでfunc1()が見つかります。その後func2()、func3()も同じライブラリ内で見つかります。

ここ以降のlibb.aは先優先のルールにより無視されますので多重定義にはならないと。


ちょっと余計な話…。

このルールによりややこしくなるのが、デフォルトで存在するライブラリ(/usr/lib/とか)です。

開発をしていて知らずにデフォルトのライブラリにある関数を自前で作成して、その関数にバグがあったりするとバグを見つけるのに一苦労w。

まあこの場合だとソースから見つけれるので良いのですが、どこかのメーカが作成したソースコード無しのライブラリでこれをやられると本当に分からないです。

lddとかstringsとかでHackするしかないです。


参考

http://www.ecoop.net/memo/2008-01-28-2.html

http://www.linux.or.jp/JM/html/GNU_binutils/man1/ld.1.html

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ