複数の定義のインライン機能をサイトにリンクされる場合の静的lib
-
19-09-2019 - |
質問
私はC++のプログラムそのコンパイルmingw gcc for Windows).のTDMリリースのmingwを含むgcc4.4.1.の実行ファイルへのリンクを二つの静的ライブラリ(.a)ファイル:には、第三者の図書室書付のC++図書館、書いた私にとっては、利用Cライブラリーを自分のC++のAPIです。
(私は、過剰分はCライブラリの機能が実施したインラインで機能する。できるなどのインライン機能をご利用の場合CライブラリのAPIがっているリンクでは、なくてはならないんリンク先のエラーの言葉がある複数の定義のインライン機能となることができるように私のC++ラッパー-図書館もっていないのに、基本的には何も定義のインラインのヘッダを頂いている機能で作成したものCライブラリは、C++ライブラリ。
な原因は複数の定義に誤りがなどのファイルを使用し複数回異なります。cいます。cppファイルを同じプロジェクトこの問題はその生成定義に当たり図書館があります。
どのようなぜ、コンパイラ生成の機能やシンボルこれらのインライン機能の両方の図書館?させるにはどうすればいいのでしで停電して私のコードについて教えてください。あるツールできるのでストリップの重複機能するために設計されています。ファイル、またはこのリンカーを無視する複数の定義は?
(参考までに、サードパーティ製ライブラリが含#ifdef__cplusplusとextern"C"を守るすべてのヘッダー;とにかくこの問題のような複数の定義のシンボル、から反対側の問題でのシンボルが未定義は少なくとも異なります。)
特に、リンク誤りが生じないだリンクの第三者へのCライブラリのDLL;しかしそう不思議なランタイムの失敗"という私のコードを、独自のバージョンの機能ならびにDLL.された場合と同様にコンパイラのある環境を整備することを目的とバージョンの機能ん。)
同様のバージョンのこの質問お問い合わせをいただいてお前はなかったい私の状況をこれらの:
この問いに対する答えたとのポスター掛けを定義する 変数, 私の問題は複数の定義のインライン機能: 繰り返し誤差の定義からど同じヘッダに複数の誘
これはMSVCプログラムが使用していmingw;また、ポスターの問題はこうした定義のC++クラスのコンストラクタが外部のクラスで身体ヘッダーは、私の問題はC関数をインライン: 静Lib複数の定義の問題
この馬鹿に改称すべてのコードをCとC++ファイルとそのCコードなC++-安心: 複数の定義多くのstd::機能本サイトにリンクされる場合
このかが知りたい、というのはなぜ違反が'一定義規則ませんでしたエラー: 予測不能な行動のインライン機能の異なる定義
解決
最初に理解し、C99インラインでモデルも違和感がありおンターフェースの通称です。ある種の定義をインライン機能の外部(静的連携
外部定義
この定義の機能でのみ表示に一度の全体プログラムには、指定されTU.での輸出の機能を使用できるからその他の研究者を迎えて実施しました。インラインの定義
これらが毎TUが宣言されたとして定義で設定します。定義はない ない 必要とする同一または外部定義で設定します。使用する場合の内部には、図書室、いを省略するかチェック関数の引数とすることで、外部定義で設定します。
の各定義の機能は、独自の地域のstatic変数, で宣言していない連携しない共通のC++).定義の静的インライン機能するインライン定義の場合
- これらの関数が宣言されていますTUの指定子
inline
, は、 - ておく機能はありません宣言TUの指定子
extern
.
そうしないと定義する必要があるTU(インライン機能が定められている必要があると同TUが宣言された)は、外部の定義で設定します。通話、インライン機能 この指定などの外部またはインラインの定義を使用.しかし、機能定義されたすべての場合も同じ(いますので外部連携のアドレスを比較しまし等しいすべての場合、どんなに多くのインラインの定義が表示されます。で利用する場合は、関数のアドレス、そのコンパイラの解決への外部定義の場合の最適化を無効).
一例として誤った使用 inline
, が含まれるすべての言語外部定義の関数倍の二つの研究が多重定義のエラー
// included into two TUs
void f(void); // no inline specifier
inline void f(void) { }
以下のプログラムは危険なので、コンパイラは外部定義のプログラムを提供しません一
// main.c, only TU of the program
inline void g(void) {
printf("inline definition\n");
}
int main(void) {
g(); // could use external definition!
}
私はテストケースに使用されることを実証する機構の更なる:
主なものです。c
#include <stdio.h>
inline void f(void);
// inline definition of 'f'
inline void f(void) {
printf("inline def main.c\n");
}
// defined in TU of second inline definition
void g(void);
// defined in TU of external definition
void h(void);
int main(void) {
// unspecified whether external definition is used!
f();
g();
h();
// will probably use external definition. But since we won't compare
// the address taken, the compiler can still use the inline definition.
// To prevent it, i tried and succeeded using "volatile".
void (*volatile fp)() = &f;
fp();
return 0;
}
main1.c
#include <stdio.h>
inline void f(void);
// inline definition of 'f'
inline void f(void) {
printf("inline def main1.c\n");
}
void g(void) {
f();
}
main2.c
#include <stdio.h>
// external definition!
extern inline void f(void);
inline void f(void) {
printf("external def\n");
}
void h(void) {
f(); // calls external def
}
現在、プログラム出力ます。
$ gcc -std=c99 -O2 main.c main1.c main2.c
inline def main.c
inline def main1.c
external def
external def
みのシンボルテーブルまでのシンボルのインライン定義には輸出から main1.o
を、外部の定義は輸出から main2.o
).
今いる場合、静的リンクライブラリそれぞれ外部定義のインライン機能としていても相互の利益が相反している。このセクションのインライン機能の静的地からの選りすぐりの名前を変更します。これらを外部定義です(その本格的な定義がない輸出されないため、社内連携という相反する
static inline void f(void) {
printf("i'm unique in every TU\n");
}