17

原則として、これはおそらく未定義の動作であることを私は知っていますが、大規模なプロジェクトを処理するために、GCCに関する私の質問は次のとおりです。

まったく同じコンパイラインストールを使用して、 1つの変換ユニットをでコンパイルしgcc -std=c++98、別の変換ユニットをでコンパイルするとします。-std=c++112つのオブジェクトファイルをリンクして、明確に定義されたプログラムを取得できるという保証はありますか?

私の知る限り、潜在的な問題は、マクロが異なるためにライブラリヘッダーのさまざまなビューからのみ発生する可能性があり、それらはせいぜい新しいメンバー関数を追加しますが、メンバーオブジェクトは標準ライブラリクラスに追加しません。

これはどういうわけか、異なる言語の方言オプションを使用して、より大きなプロジェクトの異なる部分をコンパイルすることを許容できるでしょうか?

更新:直交する質問を追加する必要があります:GCCの2つの異なるバージョン(たとえば4.3と4.6)を使用するのはどうですか?ただし、同じ方言オプション(-std=c++98)はありますか?このGCCドキュメントのリストは、ライブラリが4.2.2と4.6の間の両方向で互換性があることを示唆しているようです。

4

3 に答える 3

9

先験的に、いいえ。最も安全な解決策は、オプションがバイナリ互換性に影響を与えないことをコンパイラが具体的に文書化する場合を除いて、すべてのコンパイラオプションが同一であると想定することです。(ほとんどのコンパイラで非常に不足しているドキュメント。)実際には、ドキュメントが不足している場合、警告を制御するオプション(-W...g ++)はバイナリ互換性に影響せず、コード生成(言語)に影響するオプションは安全な賭けのようです。レベルなど)は次のようになります。g++は通常、さまざまなレベルの最適化間で互換性を維持しますが、VC++はそうではありません。

もう1つの実際の問題は、コマンドラインでプリプロセッサシンボルを定義することです。繰り返しになりますが、最も安全な方法は、すべての定義が同一であるということですが、やはり常識があります。プロジェクトで使用されるプリプロセッサシンボル(MYPROG_CONFIG_FILE_LOCATIONたとえば、 )。一方、_GLIBCXX_DEBUGおよびのプリプロセッサ定義は_GLIBCXX_DEBUG_PEDANTICバイナリ互換性に影響を与えることに注意してください(ただし、g ++は、それらを一貫して使用する場合に、それらで動作するライブラリバージョンを取得することを保証します)。

あなたの質問に関して:私は標準バージョンのためにバイナリ互換性にあまり影響を与えないと思います、選択がライブラリのバイナリ互換性を壊すような方法でいくつかの事前定義されたプリプロセッサシンボルに影響を与える場合、私はほとんど驚かないでしょう、のあるモジュールとないモジュールのいくつかをコンパイルしたかのよう_GLIBCXX_DEBUGに。それはうまくいくかもしれませんが、私はそれを当てにしません。

于 2012-05-23T09:53:53.470 に答える
3

原則として、これはおそらく未定義の動作であることを私は知っています。

そうではありません。

まったく同じコンパイラインストールを使用して、 1つの変換ユニットをでコンパイルしgcc -std=c++98、別の変換ユニットをでコンパイルするとします。-std=c++112つのオブジェクトファイルをリンクして、明確に定義されたプログラムを取得できるという保証はありますか?

はい、これはサポートされて機能します(一方のオブジェクトでデバッグモードを有効にし、もう一方のオブジェクトではデバッグモードを有効にしない、または一方のオブジェクトと他方のオブジェクトのように明示的にABIを変更するオプションを使用するなどの例外がありますが、-fshort-enumsそれは明らかではないためです。両方のオブジェクトに同じ-stdオプションを使用しても機能します)。

私の知る限り、潜在的な問題は、マクロが異なるためにライブラリヘッダーのさまざまなビューからのみ発生する可能性があり、それらはせいぜい新しいメンバー関数を追加しますが、メンバーオブジェクトは標準ライブラリクラスに追加しません。

右。

これはどういうわけか、異なる言語の方言オプションを使用して、より大きなプロジェクトの異なる部分をコンパイルすることを許容できるでしょうか?

GCCの場合、もちろんです。それがOKであることの証拠として、libstdc++.soそれ自体がで構築されたいくつかのオブジェクトとで構築されたいくつかのオブジェクトを含ん-std=c++98でいると考えて-std=c++14ください。

更新:直交する質問を追加する必要があります:GCCの2つの異なるバージョン(たとえば4.3と4.6)を使用するのはどうですか?ただし、同じ方言オプション(-std = c ++ 98)はありますか?このGCCドキュメントのリストは、ライブラリが4.2.2と4.6の間の両方向で互換性があることを示唆しているようです。

両方向ではなく、libstdc++.soGCC 4.6(またはそれ以降)からのオブジェクトを使用する必要があります。そのバージョンでコンパイルされたオブジェクトは、新しいバージョンで導入され、古いlibstdc++.soライブラリに存在しないシンボルに依存する可能性があるためです。

https://stackoverflow.com/a/49119902/981959のいくつかの関連情報

于 2018-03-05T22:15:00.317 に答える
0

言語ABIは同じですが、STLABIは異なります。https://gcc.gnu.org/wiki/Cxx11AbiCompatibilityを参照してください

したがって、-std = c ++ 98 -std = c++11でコンパイルされたライブラリを混在させることはお勧めしません。画像の境界を越えてデータを渡すと、クラッシュする可能性があります。

(extern "C"関数のみを呼び出し、PODのみを渡す場合に機能する可能性があります)。

関連項目:異なるC++標準とGCCの混合も参照してください。

于 2018-03-05T22:55:18.300 に答える