2015-07-05 84 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。

相關問題