当前位置: 华文星空 > 知识

不只是开源才有问题

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++ 标准