當前位置: 華文星空 > 知識

不只是開源才有問題

2016-12-15知識

昨天看到 @vczh 發文說 libstdc++ 實作上有bug。好漢不提當年勇,當時libstdc++敢把Regex的介面做好、實作放空這檔子事情我們就不提了。

其實何止libstdc++有bug,C++ standard也是一屁股屎擦不幹凈。

我們舉個例子(這裏援引的條款都來自於草案N4567,絕大部份都與C++14相同):

  • Allocator只要求CopyConstructible,沒說必須具有預設建構函式(17.6.3.5)。其實我覺得這個問題當初標委會就糊塗過。一個Stateless的Allocator除了TLS和Global Pool外還有個卵用啊。對於 Stateful Allocator 的話,這個Default Constructor不管雞肋還容易出錯。所以C++17到底搞了個Polymorphic Allocator;
  • Container,比如String(21.4 / 3)。對於Allocator Awareness Container(粗暴的講就是類似於Vector<T, Alloc>這樣的)來說,如果要DefaultConstructible,就需要Allocator是DefaultConstrutible的(23.2.1/16, Table 98);
  • 如果Allocator自己沒有Default Constructor,那麽String的在構造的時候必須要傳遞一個Allocator進去(23.2.1/16, Table 98)。
  • OK,其實到這裏都沒有問題。至於像什麽

    std::vector<std::vector<int, Alloc1>, Alloc2> spt;

    中的Alloc1到底是否需要 Default Constructible 這種復雜的問題,我們就不討論了。這種問題自身就相對矛盾,本來就不太好解決。

    所以,到這裏都沒問題,說明C++標準委員會的人什麽都懂。

    但是這幫子人到寫程式碼的時候還是懵逼了。 我們來看basic_string的實作(21.4.6.2):

    你不要小看這個「Effects」,實際上很多庫真的就是原模原樣這麽實作的 —— 這樣也才是個符合標準的實作。但是這個實作有什麽問題呢,對於Stateful的Allocator,比如Polymorphic Allocator(C++ 17),basic_string(first, last); 和 append 的 this 可能壓根用的就不是同一個記憶體分配器。

    如果basic_string的allocator不支持default constructor(這並沒有什麽問題),那麽basic_string(first, last) 就會導致編譯錯誤。我特麽不過用了一個allocator,你好意思讓我assign都assign不成嗎?

    一個符合標準也更加合理的實作是:

    append ( basic_string ( first , last , get_allocator ()); // Effects.

    嗯,這個問題兩個月前我report過了,在我report的時候這還不算一個known issue我猜C++17這個問題會被修正的,這也算是我為標準做了一點微小的工作。

    所以啊,Naive的並不只是開源。做C++的人,沒有不Naive的,雖然他們一點都不Simple。

    ——————————————————

    < style data-emotion-css="19xugg7"> .css-19xugg7{position:absolute;width:100%;bottom:0;background-image:linear-gradient(to bottom,transparent,#ffffff 50px);} < style data-emotion-css="12cv0pi"> .css-12cv0pi{box-sizing:border-box;margin:0;min-width:0;height:100px;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;position:absolute;width:100%;bottom:0;background-image:linear-gradient(to bottom,transparent,#ffffff 50px);}
    < style data-emotion-css="1pr2waf"> .css-1pr2waf{font-size:15px;color:#09408e;}
    編輯於 2016-12-15 09:37
    < style data-emotion-css="ch8ocw"> .css-ch8ocw{position:relative;display:inline-block;height:30px;padding:0 12px;font-size:14px;line-height:30px;color:#1772F6;vertical-align:top;border-radius:100px;background:rgba(23,114,246,0.1);}.css-ch8ocw:hover{background-color:rgba(23,114,246,0.15);}
    < style data-emotion-css="1xlfegr"> .css-1xlfegr{background:transparent;box-shadow:none;} < style data-emotion-css="1gomreu"> .css-1gomreu{position:relative;display:inline-block;}
    C++ 標準