为什么在GCC 5.1中仍然启用了COW std :: string优化?

时间:2015-07-05 08:39:58

标签: c++ string c++11 gcc copy-on-write

根据GCC 5发布更改页面(https://gcc.gnu.org/gcc-5/changes.html):

  

默认情况下启用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 [0] ='c'后x.c_str()指针会发生变化。这意味着在写入时复制内部缓冲区。所以似乎COW仍然在工作。为什么呢?

我在Ubuntu上使用g ++ 5.1.0。

1 个答案:

答案 0 :(得分: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。