了解GCC 5的_GLIBCXX_USE_CXX11_ABI或新的ABI

时间:2016-01-02 22:56:23

标签: c++ c++11 gcc

https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html

我在GCC 5上使用std :: string遇到了崩溃/ valgrind问题。上面的链接提示ABI从GCC 5.x开始发生了变化。 libstd ++的新默认ABI是C ++ 11/14 ...它与旧的ABI不兼容。有一种方法可以使用define来选择旧的ABI。

我想了解ABI和找不到详细信息之间的区别。我希望帮助理解:

  1. 需要修复std :: string的哪些问题才能与新的ABI兼容?他们是否与写作有关?
  2. 这些更改是否会破坏旧版ABI?
  3. 让_GLIBCXX_USE_CXX11_ABI工作的任何提示?
  4. 我遇到的问题的更多细节(https://github.com/YasserAsmi/jvar/issues/21)该项目在GCC 4.8和Clang中运行良好。使用GCC,相同的代码拒绝运行:

    x_misc(33112,0x7fff728c2000) malloc: *** error for object 0x7fd639c034cc:    pointer being freed was not allocated
    *** set a breakpoint in malloc_error_break to debug
    Abort trap: 6
    

    这是部分Valgrind输出:

    ==33027== Invalid read of size 1
    ==33027==    at 0x1006F78BA: _platform_memmove$VARIANT$Nehalem (in /usr/lib/system/libsystem_platform.dylib)
    ==33027==    by 0x100009388: jvar::Variant::toString[abi:cxx11]() const (in bin/ex_misc)
    ==33027==    by 0x1000023A7: bugreport() (in bin/ex_misc)
    ==33027==    by 0x1000133B8: main (in bin/ex_misc)
    

    该项目使用std :: string并具有一些自定义内存管理。它正在使用放置新构造函数等进行一些非典型但有效的操作。我试图更好地理解API对哪种代码的影响以及如何修复它 - 一个起点。

2 个答案:

答案 0 :(得分:11)

  1. std::string不符合C ++ 11,因为该标准禁止写入时复制实现。在没有破坏ABI的情况下无法创建符合条件的std::string,因此他们通过返回不兼容的版本来实现ABI兼容性。

  2. 确保程序中的所有翻译单元使用相同的_GLIBCXX_USE_CXX11_ABI值,您应该没问题。如果你将它们混合在翻译单元中,你肯定会遇到问题。如果您在不同的翻译单元中使用不同的定义值,那么可能可以正常。{/ p>

答案 1 :(得分:4)

COW和非COW字符串之间存在一个有趣的区别,例如:

std::string some_string;
std::string foo()
{
   return some_string;
}

char const *s = foo().c_str();
printf("%s\n",s);

这可以使用COW字符串作为c_str(),由some_string返回,foo指向同一个内存,但是当它不是COW时,一旦foo返回的std :: string被销毁,s将失效

从样本中你应该看看这个方向。