2015-07-05 56 views
4

根据GCC 5的发布改变了页面(https://gcc.gnu.org/gcc-5/changes.html):为什么COW std :: string优化在GCC 5.1中仍然可用?

的std :: string的一个新的实现是默认启用的,使用小串的优化,而不是写入时复制引用计数

我决定进行检查,并写了一个简单的程序:

int main() 
{ 
    std::string x{"blah"}; 
    std::string y = x; 
    printf("0x%X\n", x.c_str()); 
    printf("0x%X\n", y.c_str()); 
    x[0] = 'c'; 
    printf("0x%X\n", x.c_str()); 
    printf("0x%X\n", y.c_str()); 
} 

,其结果是:

0x162FC38 
0x162FC38 
0x162FC68 
0x162FC38 

请注意,x.c_str()指针在x [0] ='c'之后改变。这意味着内部缓冲区在写入时被复制。所以看起来COW仍在工作。为什么?

我在Ubuntu上使用g ++ 5.1.0。

+6

我想你的发行版上的gcc的配置与默认配置不同,以保持ABI兼容性。 – inf

+0

你说得对。我用-D _GLIBCXX_USE_CXX11_ABI编译它,现在按预期工作(没有COW和动态内存分配,所以显然SSO正在使用)。 –

回答

8

有些发行版有意偏离FSF GCC选择以默认为新的ABI。 Here's an explanation of why Fedora 22 deviates from upstream GCC like that.总之:

在一个程序中,最好不要混合旧的和新的ABI,而是选择一个并坚持下去。如果程序的一部分假定某个类型的内部表示不同于该程序的另一部分,则结果会中断。

因此,如果使用任何使用旧C++ ABI的C++库,那么使用该库的程序也应该使用旧的C++ ABI。

因此,如果使用的是使用GCC 4.9或更早版本构建的C++库,那么使用该库的程序也应该使用旧的C++ ABI。

Fedora 22仍然提供(或提供?)很多使用GCC 4.9构建的库,因为没有足够的时间在Fedora 22发布之前用GCC 5.1重建它们。为了允许程序使用这些库,GCC默认切换到旧的ABI。

据我所知,GCC 5并不是Ubuntu中的默认编译器(但很快就会发布),所以如果它是作为额外安装提供的,Fedora的相同参数也适用于Ubuntu。

相关问题