10

我最近花了相当多的时间来跟踪一个问题,该问题是由编译一个库引起的-D_GLIBCXX_DEBUG(它告诉 libstdc++ 使用带有额外检查的标准库的调试版本)但编译客户端程序时没有。这导致了 ABI 兼容性问题。

有什么方法可以用 GCC 自动检测这样的问题吗?Visual Studio 提供了我认为可以达到此目的的detect_mismatch编译指示,但我不知道任何 GCC 等效项。GLIBCXX_3.4.9GCC做了一些嵌入符号名称(mylib_debug_stl例如使用那个符号真的很hacky。

或者,其他人如何避免这个问题?将库的检查版本构建为不同的名称或类似名称?

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;
  // ...
};

然后,当我想为该特定类使用调试模式向量时,我会更改预处理器条件,而不影响程序中的每个容器。因为更改涉及写入文件(并因此更新其时间戳)任何依赖于该标头的内容都将由 重建make,并且有两种不同的类型std::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 回答