2012-01-17 1 views
0

「IBM Rational Rhapsody 7.5」の共有オブジェクトプロジェクトをqccで構築しています。これはgccを使用します。プリプロセッサディレクティブによる共有オブジェクトの不一致

全く同じビルド環境を持つ2つの異なるマシンに同じコードをビルドすると、バイナリのミスマッチが発生します。

いくつかの試行錯誤の後で、コードの条件付き実行(#ifdefを使用)に使用されるpre-processsorディレクティブに起因する不一致が観察されました。プリプロセッサディレクティブが削除され、プロジェクトが別の2つのバイナリは正確に一致します。

「なぜこのミスマッチが発生するのですか?」という理由はありますか?

プリプロセッサディレクティブは、オブジェクトファイル内にマシン依存のパラメータを追加するため、実行可能ファイルに反映され、不一致を示しますか? 私を案内してください。

+1

'#ifdef'ブロック内にはどのようなコードがありますか?そのことを知らずに問題が何であるかを知ることは不可能です。 – Mat

+1

ディレクティブはどのようなシンボルをテストしますか? – Bingo

+0

CPUの種類、OSのバージョン、カーネルのバージョン、コンパイラのバージョンなど、2つの環境には多少の違いがあるはずです。慎重に確認してください。 – ciphor

答えて

0

プリプロセッサディレクティブ#ifdefは条件付きコンパイルを行います。これがバイナリの非互換性につながるかどうかは、#ifdefと対応する#endifの間にあるかどうかによって決まります。たとえば、次のように明らかにまったく影響がないでしょう。

#ifdef FOO 
#endif 

FOOが定義されているかどうかは関係ありませんが、コンパイルされたコードはまったく同じに見えます。

ただし、以下は確かに非互換性の原因となります。

ここ
#ifdef HAS_FOO_STRUCT 
typedef foo foo_type; 
#else 
struct foo_type {}; 
#endif 

void bar(foo_type); 

、HAS_FOO_STRUCTが定義されている場合、bar(foo_type)が実際にbar(foo)であり、そのようなものとして台無しされます。一方、HAS_FOO_STRUCTが定義されていない場合、foo_typeは実際にこの名前のタイプです。したがって、bar(foo_type)はその名前をmangled inにします。これはバイナリの非互換性があります。

定義されたマクロの違いは、いくつかの異なる場所から来る場合があることに注意してください。第1に、異なるコンパイラバージョンが異なるマクロを定義する(またはマクロを異なる値に定義する)ことがあります。たとえば、コンパイルするシステムのタイプを識別するマクロと、コンパイラのバージョンを識別するマクロがあります。マクロの相違点は、システムヘッダーファイルに由来する可能性があります。これは異なる#defineを持つ可能性があります。さらに、ビルドシステムは、システム上に特定のもの(例えば、プリインストールされたライブラリ)が見つかったか見つからなかったかを示すマクロを定義することができる。

コンパイル時に表示されないより微妙なバイナリの非互換性を防ぐために、バイナリの非互換性は意図的である可能性があることに注意してください。

+0

私は全く同じビルド環境(コンパイラのバージョンなど)を持つ2つの異なるマシン上に同じ共有ライブラリ(つまり同じコード)を構築しようとしています。どちらのマシンでも、両方のマシンでプリプロセッサ・ディレクティブが定義されているので、コンパイルされるコードは同じになります。 両方のマシンでディレクティブの定義が削除された場合、バイナリは正確に一致します。 コンパイルされたコードが両方のマシンで同じになっていても、プリプロセッサディレクティブはどのようにミスマッチを作成していますか? – user1153298

+0

これらのマシンにもまったく同じライブラリがインストールされていますか?特に問題の共有ライブラリで使用されているライブラリについては? – celtschk

+0

はい、使用するライブラリは同じです。 – user1153298

関連する問題