10

私は最近、かなりの時間を費やして、ライブラリをコンパイルすることによって引き起こされたことが判明した問題を追跡しました-D_GLIBCXX_DEBUG(これは libstdc++ に追加チェック付きの標準ライブラリのデバッグ バージョンを使用するように指示します)。これにより、ABI の互換性の問題が発生しました。

GCC でこのような問題を自動的に検出する方法はありますか? Visual Studioには、この目的に役立つと思われるdetect_mismatchプラグマが用意されていますが、GCC に相当するものは知りません。GCC はシンボル名 (例: ) を埋め込むことで何かを行いGLIBCXX_3.4.9ます。対応するシンボル (例: ) が存在しない場合、未定義のシンボルが原因でリンク エラーが発生するスキームを想像mylib_debug_stlできますが、そのシンボルの使用は本当にハックです。

あるいは、他の人はこの問題をどのように回避しますか? ライブラリのチェック済みバージョンを別の名前またはそのようなものにビルドしますか?

4

2 に答える 2

4

GCC でこのような問題を自動的に検出する方法はありますか?

コンパイラではなく、互換性のないコードをリンクしたかどうかを検出できるのはリンカーだけです。

代替リンカー はgold、オプションに関するいくつかの問題を検出でき--detect-odr-violationsます。

あるいは、他の人はこの問題をどのように回避しますか? ライブラリのチェック済みバージョンを別の名前またはそのようなものにビルドしますか?

デバッグ モードを使用したい場合は、すべてを再構築するようにしています。デバッグ モードで構築されたライブラリを保持したいと思ったことは一度もありません。通常の使用ではなく、デバッグ用です。

とにかくめったに使用-D_GLIBCXX_DEBUGしません。より頻繁に次のようなことを行います。

#if 0
# include <debug/vector>
namespace my_class_stl = __gnu_debug;
#else
#include <vector>
namespace my_class_stl = std;
#endif

struct my_class
{
  typedef my_class_stl::vector<int> container;
  typedef container::iterator iterator;
  // ...
};

次に、プログラム内のすべてのコンテナーに影響を与えることなく、その特定のクラスにデバッグ モード ベクトルを使用する場合に、プリプロセッサの条件を変更します。変更にはファイルへの書き込み (およびそのタイムスタンプの更新) が含まれるため、そのヘッダーに依存するものはすべてによって再構築さmakestd::vector<int>ます__gnu_debug::vector<int>

定義するだけ_GLIBCXX_DEBUGでは、すべての依存関係が再構築されるわけstd::vectorではなく、特定のコンテナーを別の名前の別の型に変更するのではなく、グローバルの定義を静かに変更します。__gnu_debug::vector

于 2012-09-30T22:00:48.033 に答える
0

-D_GLIBCXX_DEBUG (libstdc++ に追加チェック付きの標準ライブラリのデバッグ バージョンを使用するように指示する) を使用してライブラリをコンパイルし、それを使用せずにクライアント プログラムをコンパイルしたことが原因であることが判明しました。

このような構成をサポートすることは、明示的なデバッグ モードの設計目標であり、それが問題の 実際の原因でlibsdc++あったとは思えません。

を使用せずにライブラリを再構築した後、問題が解消された可能性がありますが、非互換性が根本的な原因であった-D_GLIBCXX_DEBUGことを証明するものではありません。ABI

于 2012-10-13T23:25:07.347 に答える