掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.28757

異なる翻訳単位での同じ関数
投稿者---RiSK(2006/11/05 23:14:28)


異なる翻訳単位で識別子が同じ関数がある場合,リンクしたときにどうなるかは,規格で定められていますか?

1.識別子も内容(実装)も全く同じ場合
最適化される可能性はありますか?
VC6ではコンパイルはOKでリンク時に
a.obj : error LNK2005: _imp はすでに imp.obj で定義されています
b.obj : error LNK2005: _imp はすでに imp.obj で定義されています
Debug/a.exe : fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました
link.exe の実行エラー
ってなりました。
例:
// imp.c
int imp(void){return 0;}
// a.h
int a(void);
// a.c
#include"imp.c"
int a(void){return imp();}
// b.h
int b(void);
// b.c
#include"imp.c"
int b(void){return imp();}
// main.c
#include<stdio.h>
#include"a.h"
#include"b.h"
int main(void){
    printf("%d %d\n",a(),b());
}

2.識別子は同じだが実装が違う場合


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:異なる翻訳単位での同じ関数 28758 επιστημη 2006/11/05 23:52:46
<子記事> Re:異なる翻訳単位での同じ関数 28760 たかぎ 2006/11/06 10:06:29


No.28758

Re:異なる翻訳単位での同じ関数
投稿者---επιστημη(2006/11/05 23:52:46)
http://blogs.wankuma.com/episteme/


>異なる翻訳単位で識別子が同じ関数がある場合,リンクしたときにどうなるかは,規格で定められていますか?

規格書を読んではいかがでしょうか?



この投稿にコメントする

削除パスワード

No.28762

Re:異なる翻訳単位での同じ関数
投稿者---RiSK(2006/11/06 10:25:53)


回答ありがとうございます。

>規格書を読んではいかがでしょうか?

えぇ。がんばって関係ありそうなところを探しているんですけど,
宣言については(当然ながら)書いているのですが,
定義について書いてある箇所を見つけられません。

規格書の 5.1.1.1,5.1.1.2,6.2.2 あたりも
(私が読み間違っていなければ)ハズレっぽい。

規格に書いていない=未定義 ってことなのかなぁ。

実際,VC6がブー垂れてるので,最適化される
(リンカが気をつかって関数impを一つだけ選んでリンクしてくれる)
なんてあまり期待はしてないのですけど。気になるなぁ。


あーそうそう,元の imp.c の 関数 imp を static にすると
当然ながらリンクまでうまくいきます。
この場合も,リンク時に(サイズの)最適化は期待できないのだろうなぁ…。


この投稿にコメントする

削除パスワード

No.28760

Re:異なる翻訳単位での同じ関数
投稿者---たかぎ(2006/11/06 10:06:29)
http://takagi.in/


>異なる翻訳単位で識別子が同じ関数がある場合,リンクしたときにどうなるかは,規格で定められていますか?

C++の場合は、単一定義規則で、(テンプレートやインライン関数のような例外を除けば)プログラム全体を通じてちょうど一つしか定義があってはならないことが明記されていますが、Cの場合は特に明記されていなかったと思います(つまり未定義)。

>1.識別子も内容(実装)も全く同じ場合
>最適化される可能性はありますか?

最適化というか、マニュアルでそのように振る舞うことが明記されていれば、可能性はあると思います。ただ、多くの処理系がC++処理系を兼ねていることを考えると、可能性はほとんどないでしょう。

それに、内容が同じというのは字句の並びが同じというだけではなく、中で参照している識別子の実体が同じであり、各翻訳単位のコンパイルオプションも同じであることも保証する必要がありますね。

>2.識別子は同じだが実装が違う場合

リンク時に同一性を判断しないといけないので、リンクが非常に遅くなると思いますが、定義が同じ場合にマージされるのであれば、これはエラーにならないと困りますね。



この投稿にコメントする

削除パスワード

No.28763

Re:異なる翻訳単位での同じ関数
投稿者---RiSK(2006/11/06 10:42:37)


回答ありがとうございます。
επιστημηさんへの返信を書いている間に入れ違いになってしまいました。


>>異なる翻訳単位で識別子が同じ関数がある場合,リンクしたときにどうなるかは,
>規格で定められていますか?
>(snip)
>Cの場合は特に明記されていなかったと思います(つまり未定義)。

やっぱりそうでしたか,ありがとうございます。
すっきりしました。


>>1.識別子も内容(実装)も全く同じ場合
>>最適化される可能性はありますか?
>
>最適化というか、マニュアルでそのように振る舞うことが明記されていれば、
>可能性はあると思います。ただ、多くの処理系がC++処理系を兼ねていることを考えると、
>可能性はほとんどないでしょう。
>
>それに、内容が同じというのは字句の並びが同じというだけではなく、
>中で参照している識別子の実体が同じであり、
>各翻訳単位のコンパイルオプションも同じであることも
>保証する必要がありますね。

なるほど,可能性はほとんどありませんか。
コンパイルオプションまでは考えていませんでした。


>>2.識別子は同じだが実装が違う場合
>
>リンク時に同一性を判断しないといけないので、リンクが非常に遅くなると思いますが、定義が同じ場合にマージされるのであれば、これはエラーにならないと困りますね。

そうですね。
いやー勉強になりました。ありがとうございます。



ところで,

>C++の場合は、単一定義規則で、(テンプレートやインライン関数のような例外を除けば)
>プログラム全体を通じてちょうど一つしか定義があってはならないことが
>明記されていますが、

この括弧書きの例外についてもう少し詳しく知りたいのですが,
別スレを建てた方がいいような,話題/ボリュームだったりしますか?
良ければこのスレに返信をいただけるとうれしいです。


この投稿にコメントする

削除パスワード

No.28764

Re:異なる翻訳単位での同じ関数
投稿者---たかぎ(2006/11/06 10:58:04)
http://takagi.in/


>>C++の場合は、単一定義規則で、(テンプレートやインライン関数のような例外を除けば)
>>プログラム全体を通じてちょうど一つしか定義があってはならないことが
>>明記されていますが、
>
>この括弧書きの例外についてもう少し詳しく知りたいのですが,
>別スレを建てた方がいいような,話題/ボリュームだったりしますか?
>良ければこのスレに返信をいただけるとうれしいです。

別スレの方がいい気はしますが(C++の話題だし)、面倒なのでここで書きます。

JIS X3014:2003 3.2 単一定義規則の段落5に明記されています。
 クラス型, 列挙型, 外部結合をもつインライン関数, クラステンプレート, 静的でない関数テンプレート, クラステンプレートの静的なデータメンバ, クラステンプレートのメンバ関数, 及び 指定のないテンプレート仮引数をもったテンプレート特殊化については, 一つのプログラムの中に複数の定義があってもよい。
クラス型や列挙型はともかく、実体を伴うものとしては、やはりインライン関数(関数内部で宣言される静的オブジェクトを含む)とテンプレートですね。
この後に但し書きもあるので、正確な内容は規格書を読むことをお勧めします。



この投稿にコメントする

削除パスワード

No.28765

Re:異なる翻訳単位での同じ関数
投稿者---RiSK(2006/11/06 11:15:11)


回答ありがとうございます。

>別スレの方がいい気はしますが(C++の話題だし)、面倒なのでここで書きます。

恐縮です。

>JIS X3014:2003 3.2 単一定義規則の段落5に明記されています。
>(snip)
>この後に但し書きもあるので、正確な内容は規格書を読むことをお勧めします。

読んでみました。Cと比較して,前から疑問に思っていた
C++のテンプレートについても知ることができました。


みなさん,ありがとうございました。
以上でこのスレッドは閉じたいと思います。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧