Why is COW std::string optimization still enabled

2019-02-24 06:36发布

问题:

According to GCC 5 release changes page (https://gcc.gnu.org/gcc-5/changes.html):

A new implementation of std::string is enabled by default, using the small string optimization instead of copy-on-write reference counting

I decided to check it and wrote a simple program:

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());
}

And the result is:

0x162FC38
0x162FC38
0x162FC68
0x162FC38

Notice that the x.c_str() pointer changes after x[0] = 'c'. This means that the internal buffer is copied upon write. So it seems that COW is still in work. Why?

I use g++ 5.1.0 on Ubuntu.

回答1:

Some distributions intentionally deviate from the FSF GCC choice to default to the new ABI. Here's an explanation of why Fedora 22 deviates from upstream GCC like that. In short:

In a program, it's best not to mix the old and the new ABIs, but to pick one and stick with it. Things break if one part of the program assumes a different internal representation for a type than another part of the program.

Therefore, if any C++ library is used that uses the old C++ ABI, then the programs using that library should also use the old C++ ABI.

Therefore, if any C++ library is used that was built with GCC 4.9 or earlier, then the programs using that library should also use the old C++ ABI.

Fedora 22 still provides (or provided?) a lot of libraries built with GCC 4.9, because there wasn't enough time to rebuild them all with GCC 5.1 before the Fedora 22 release. To allow programs to use those libraries, the GCC default was switched to the old ABI.

As far as I can tell, GCC 5 isn't the default compiler in Ubuntu yet (but will soon be), so if it's provided as an extra install, those same arguments from Fedora also apply to Ubuntu.