11

C ++プロジェクトのテストにGoogleTestを使用していますが、プリコンパイルされたライブラリがUbuntuパッケージで配布されていないことを確認した後、プロジェクトのWebサイトで次の情報を見つけました。

異なるコンパイラフラグを使用してGoogleTestとテストコードをコンパイルすると、同じクラス/関数/変数の異なる定義が表示される場合があります(たとえば、Google Testで#ifを使用しているため)。したがって、正気を保つために、コンパイル済みのGoogleTestライブラリをインストールしないことをお勧めします。代わりに、各プロジェクトは、Google Testとテストの両方に同じフラグが使用されていることを確認できるように、GoogleTest自体をコンパイルする必要があります。

私がこれから得たのは、テストしているプロジェクトとは別にGoogleTestをコンパイルするのは悪い考えだということです。私が理解していないのは、これが単なるGoogleTestの問題なのか、それともライブラリをリンクするための一般的な問題なのかということです。

質問

プリコンパイルされたサードパーティライブラリ、コンパイラフラグなどにリンクするのが安全でない状況はありますか?そうでない場合、GoogleTestの何が特別なのですか?

4

1 に答える 1

6

問題を引き起こす可能性のあるコンパイラフラグ、特にアライメントで機能するフラグがいくつかあります。

GCCi386およびx86-64フラグから

-malign-double
-mno-align-double

GCCがdouble、long double、およびlonglong変数を2ワード境界または1ワード境界のどちらに整列させるかを制御します。ダブル変数を2ワードの境界に揃えると、メモリが増えますが、Pentiumでいくらか高速に実行されるコードが生成されます。

x86-64では、-malign-doubleがデフォルトで有効になっています。

警告:-malign-doubleスイッチを使用すると、上記のタイプを含む構造体は、公開されている386のアプリケーションバイナリインターフェイス仕様とは異なる方法で配置され、そのスイッチなしでコンパイルされたコードの構造体とバイナリ互換性がありません。

たとえば、32ビットシステムでそのフラグを使用すると、doubleとlonglongが64ビットで整列されます。フラグなしでライブラリをコンパイルし、フラグを使用しながらライブラリを使用しようとすると、上記のタイプを含む構造体の配置が異なり、相互運用できない場合があります。

他の(はるかに単純な)ケースでも、同じ関数/構造/クラス定義が使用されるように(および他のそのようなODR違反)、同じ#definesのセットを保証することができます。たとえば、gccで'--std = c ++ 11'を使用すると、標準ライブラリクラスのC ++ 11バージョンが有効になります。これにより、以前のバージョンとは異なる場合があります。

于 2012-10-12T21:24:43.070 に答える