1

私はしばらくの間、オープンソースライブラリ(「高速人工ニューラルネットワーク」)を使用してきました。静的ライブラリのソースを使用しています。ただし、コンパイルすると、ライブラリに他の*.cファイルに*.cファイルが含まれているという事実が原因である可能性のある何百ものリンカー警告が表示されます(必要なヘッダーのみが含まれていて、触れなかったため) lib自体のコード)。

私の質問:ライブラリの開発者がこのアプローチを使用した理由はありますか?これは強く推奨されていませんか?(または、少なくとも私はこれが悪いと私の人生を通して言われました、そして私自身の経験から私はそれが悪いと信じています)。それとも、それは単に悪い設計であり、このアプローチには利益がありませんか?

私はこの関連する質問を知っていますが、それは私の質問に答えません。私はこれを正当化するかもしれない理由を探しています。

ボーナスの質問:ライブラリコードにあまり触れずにこれを修正する方法はありますか?私は自分の仕事がたくさんあり、これ以上作成したくありません;)

4

6 に答える 6

3

私が見る限り(grep '#include .*\.c')、彼らはdoublefann.c、fixedfann.c、floatfann.cでのみこれを行い、毎回理由が含まれています:

/* Easy way to allow for build of multiple binaries */

単純なコピー貼り付けのためのプリプロセッサのこの正確な使用は、実際、実装(* .c)ファイルを含める唯一の有効な使用法であり、比較的まれです。(別の理由でコードを含める場合は、*。hや* .incなどの別の名前を付けてください。)別の方法は、コンパイラーに指定されたマクロで構成を指定することです(たとえば、-DFANN_DOUBLE、-DFANN_FIXED、または-DFANN_FLOAT)、ただし、このメソッドは使用しませんでした。(それぞれのアプローチには欠点があるので、必ずしも間違っているとは限りません。それを判断するには、そのプロジェクトを詳しく調べる必要があります。)

それらは、doublefann.o(doublefann.cから)をfann.o(fann.cから)またはfixedfann.o(fixedfann.cから)などとリンクしてはならないmakefileおよびMSVSプロジェクトを提供し、それらのファイルは失敗したか、同様の問題が発生しました。

プロジェクトを最初から作成して(または既存のプロジェクトを使用して)、すべてのファイルをプロジェクトに追加しようとしましたか?そうした場合、起こっているのは、各実装ファイルが独立してコンパイルされており、結果のオブジェクトファイルに競合する定義が含まれていることです。これは実装ファイルを処理するための標準的な方法であり、多くのツールがそれを前提としています。考えられる唯一の解決策は、プロジェクト設定を修正して、これらをリンクしないようにすることです。(さて、あなたもそれらのソースを大幅に変更することができますが、それは実際には解決策ではありません。)

その間、プロジェクト設定を使用せずに続行すると、fann.cなどのコンパイルをスキップできる可能性があります。al。そして、おそらくプロジェクトからそれらを削除するだけで十分です–そうすると、それらはコンパイルおよびリンクされません。使用するdouble-/fixed-/ floatfannのいずれかを正確に選択する必要があります。そうしないと、同じリンクエラーが発生します。(私は彼らの指示を見ていませんが、この要約がもう少し詳細に説明されているのを見て驚くことはありません。)

于 2010-07-12T09:23:42.087 に答える
2

C / C ++コードを含めると、すべてのコードが1つの変換ユニットにまとめられます。優れたコンパイラを使用すると、これにより大幅な速度の向上につながる可能性があります(インライン化して関数呼び出しを最適化できるため)。

ただし、実際のコードがこのように含まれる場合はstatic、ほとんどの宣言に含まれている必要があります。そうしないと、表示される警告が発生します。

于 2010-07-12T09:05:36.720 に答える
0

その.cファイルで単一のグローバル変数または関数を宣言した場合、両方が同じバイナリにコンパイルされる2つの場所に含めることはできません。そうしないと、2つの定義が衝突します。1つの場所に含まれている場合でも、ユーザーと同じバイナリにリンクされている間は、単独でコンパイルすることはできません。

ファイルが1つの場所にのみ含まれている場合は、それを個別のコンパイル単位にする(そしてextern宣言を介してそのグローバルを使用する)のはなぜですか?なぜそれを含めるのが面倒なのですか?

Cファイルがグローバル変数または関数を宣言していない場合、それらはヘッダーファイルであり、そのように名前を付ける必要があります。

したがって、徹底的な検索によって、Cファイルを含める可能性があるのは、同じCコードを使用して複数の異なるバイナリを作成する場合のみであると言えます。そして、そこでさえ、実際の利益なしにコンパイル時間を増やしています。

これは、インライン化する必要のある関数がマークされinlineており、適切なコンパイラとリンカがあることを前提としています。

これを修正する簡単な方法がわかりません。

于 2010-07-12T09:05:21.760 に答える
0

私はそのライブラリを知りませんが、あなたがそれを説明するように、それは悪い習慣であるか、それをどのように使うかについてのあなたの理解は十分ではありません。

他の人に含めたいACプロジェクトは、常に他の人に適切に構造化された.hファイルを提供し、次にリンク用にコンパイルされたライブラリを提供する必要があります。関数定義をヘッダーファイルにインクルードする場合は、それらをstatic(旧式)またはinline(C99以降で可能)としてマークする必要があります。

于 2010-07-12T09:09:20.107 に答える
0

コードを見ていませんが、含まれている.cまたは.cppファイルに実際にヘッダーで機能するコードが含まれている可能性があります。たとえば、テンプレートやインライン関数。その場合、警告は偽物になります。

于 2010-07-12T09:09:31.430 に答える
0

私はLinux上のC++に比較的慣れていないので、リンカーの問題に悩まされたくないので、現在自宅でこれを行っています。しかし、私は適切な仕事のためにそれをお勧めしません。

(また、Rational Roseはヘッダーを発行されたソフトウェアの一部にすることを許可しておらず、実行中のシステムにその特定のソースファイルが必要だったため(難解な理由で)、header.datをC++プログラムに含める必要がありました。)

于 2010-07-12T09:25:35.697 に答える