1

シナリオ 1: 新しいライブラリ (libA) を自分のプログラムにリンクしたいのですが、libA は -std=gnu99 フラグを指定して gcc を使用してビルドされていますが、私のプログラムの現在のライブラリはそのオプションなしでビルドされています (gcc が -std= を使用すると仮定します)。デフォルトでは gnu89)。

シナリオ 2: libB は、"-D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED" のようないくつかのプリプロセッサ フラグを使用してビルドされ、XPG4 機能 (たとえば、struct msghdr の msg_control メンバー) を有効にします。libC はこれらのプリプロセッサ フラグなしでビルドされたわけではありませんが、libB に対してリンクされています。

異なるプリプロセッサ フラグまたは C 標準でビルドされたライブラリをリンクするのは間違っていますか? 私の懸念は、主に構造定義の不一致に関するものです。

ありがとう。

4

2 に答える 2

0

シナリオ 1 は完全に安全です。std=オプションは、標準との互換性のためにコードをチェックしますが、ABI とは何の関係もないため、プリコンパイルされたコードをさまざまな std オプションと自由に組み合わせることができます。

シナリオ 2 は安全でない可能性があります。ここでは簡単な例を 1 つだけ紹介しますが、実際のケースはもっと難しい場合があります。

次のような機能があるとします。

#ifdef MYDEF
int foo(int x) { ... }
#else
int foo(float x) { ... }
#endif

そして、あなたは、となしでコンパイルa.oし、関数fromは関数inを呼び出します。次に、それを一緒にリンクすると、すべてがうまくいくようです。次に、実行時にすべてが失敗し、呼び出された側で float を期待しているのに、なぜ 1 つのモジュールから int を渡すのかをデバッグするのに非常に苦労する可能性があります。-DMYDEFb.obara.ofoob.o

よりトリッキーなケースには、条件付きで定義された構造体フィールド、呼び出し規則、グローバル変数のサイズが含まれる場合があります。

PSすべてのソースが同じ言語で書かれており、stdオプションとマクロ定義のみが異なると仮定します。C と C++ のコードを組み合わせるのは非常に難しい場合があります。Mikhail に同意します。

于 2013-01-24T09:09:01.810 に答える
0

私が構造定義の不一致に遭遇したのは、C と C++ のコードを組み合わせたときでした。これらの場合、何かひどいことが起こっているという明確な警告がありました。何かのようなもの

/usr/lib/gcc/i586-suse-linux/4.3/../../../../i586-suse-linux/bin/ld: Warning: size of symbol `tree' changed from 324 in /tmp/ccvx8fpJ.o to 328 in gpu.o

その質問を参照してください。

于 2013-01-24T08:40:35.330 に答える