幻の上帝吧 关注:328贴子:3,165
  • 24回复贴,共1

[原创]杂物堆

只看楼主收藏回复

此处存放没找到更合适放到其它贴内的issue和考据之类的事项。


IP属地:北京1楼2015-05-08 06:07回复
    补喂熊。


    IP属地:北京2楼2015-05-08 06:09
    回复
      libstdc++ 4.9的basic_stringstream的复制构造和复制赋值private,复制赋值的post还没实现……看trunk里倒是实现了C艹11要求的东西。
      果然之前偷工减料太多了么。


      IP属地:北京3楼2015-05-08 06:11
      回复
        陈硕《iostream 的用途与局限》相关还是有一坨错误要整,完整的当TODO算了。
        http://blog.csdn.net/solstice/article/details/6612179
        ```
        注意到 ostringstream 会用到动态分配内存
        ```
        这个至少按现在的libstdc++实现是错的。std::basic_stringbuf里用的缓存直接拿了个basic_string,在字符串不太大的情况下SSO不需要动态分配。
        说到底,ISO C++是不管这种破事。不过std::basic_streambuf搞了这么坨*gptr(),按常理出牌的实现都会把缓存扔给派生类,不脑残的实现自然想得到SSO之类。
        当然说libstdc++ 5之前的string用了COW的实现导致烂,那只能呵呵。
        话说回来,如果用ISO C那坨stdio,那基本只会更烂(比如sync_with_stdio,呵呵)。struct FILE的一般实现也和streambuf差不了多少,而又没有stringbuf的对应物。用FILE*的策略艹memory stream简直呵呵。除开ABI之类的问题,API意义上唯一的强项就是扩展——比如POSIX的*_unlocked。但这反而侧面说明了ISO C的翔。破事例子参照:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=45574
        另一方面,libstdc++的filebuf还是靠stdio,为啥这里就没啥存在感jjyy了,就有点奇怪了。只是因为和C差不多?继续呵呵。


        IP属地:北京4楼2015-05-08 06:24
        收起回复
          http://www.zhihu.com/question/30703519
          挂的不是回答本身,只是引子。
          首先是配菜。
          ```
          陈甫鸼,生长于闽,求学入秦,漂泊适燕,实秦人也。
          ...
          Winter 对王垠的观点有不满,这一点似乎没有疑问。事实上,我对王垠这两年来的状态也不喜欢。我曾经严厉地批评过一次王垠的这篇文章:《什么是“脚本语言”》。 我批评他利用了诡辩术中稻草人谬误的手法,通过树立一个和设计目标和现实完全不符的脚本语言的「定义」,来批评脚本语言的所谓种种不合理。这不是一个严肃 的学者应该有的态度。但 winter 并没有解释过他对王垠的恶感从何而来,而我在那个回答里也没有阐述。因而也就有很多粉丝们反对,说王垠的水平很高,他说的话揭示了深刻的问题,你们没资格 这样指责他,云云。
          ```
          说的大概是这个。
          http://www.zhihu.com/question/20898488/answer/16852438
          说了一堆,可惜没啥卵用。
          王垠那篇《什么是“脚本语言”》的中心说白了其实很简单:“脚本语言”这概念已经臭了,没必要用。
          (反正都打引号了嘛……)
          然而答主看样子就是一厢情愿以为王垠的目的出发就是婊某些具体语言了。其实当事人大概是有些这个意思,但至少不是那篇文章的重点。
          虽然王垠对概念本义的理解一贯拙计,没讲出外延和内涵什么的所以然,但只是这个论点和论据并没有大问题:所谓的“脚本语言”,大部分用户也就是这样误解的——能勉强说出部分外延,讲不清内涵。
          比如这里:
          http://www.douban.com/note/269181191/
          http://zhidao.baidu.com/question/4443639.html?loc_ans=19301254
          是不是脚本语言和语言在实现时是不是被解释本来就八竿子打不着。
          既然如此,在不扔掉“解释语言(实现)”这样明显更有用的概念的前提下,为了减少误会扔掉不知所谓的“脚本语言”这种说法也没什么好奇怪的。
          原文的观点基本上是围绕着这样的动机来展开——不就是多泼脏水嘛。
          ```
          通篇读下来,不难看出,这篇文章最根本的毛病不在于逻辑,而在于证据环节。它试图以「不够严谨的设计损害工程上的可用性」这个隐含的大前提,以及「脚本语言的设计不够严谨」这一小前提,推出「脚本语言损害工程上的可用性」这个结论。
          ```
          所以说这个结论是把写作目的都搞错了。
          还有个包括其它我到处都有找过的、各个评论者都有硬伤就是——不管三七二十一直接评论原文对脚本语言的观点,却不先澄清“脚本语言”这玩意儿到底是什么。
          为啥呢?难道是没能耐或是不敢?——不对,这样就该没底气评论了。
          实际上“脚本语言”大致上的定义还是比较清楚的,具体有兴趣自己喂鸡。
          ——我说上面这话的理由有这样几点:
          一、“脚本语言”究竟是什么,并不会改变王垠原文观点的有效性和适用性(重点在于,光是对“脚本语言”的理解普遍混乱成这样,这玩意儿就只配当个过气历史名词了)。
          不管怎么说,误会就是误会。扯不清楚,躲得起,行了吧?
          二、显然,没有争议的是脚本语言的“脚本”来自于工程需求。但是不是作为“脚本”的语言就能叫做“脚本语言”呢?这是另一个问题。展开了基本就是和王垠一样的废话,鸡同鸭讲太无趣了,反而像这里的回答一样继续转移视线,让读者纠结在无关紧要的地方上浪费时间。


          IP属地:北京9楼2015-05-30 08:59
          收起回复
            ```
            我的证据是:作者通篇都在拿 Bash 的语言特征指代一般脚本语言,而闭口不谈 Python 和 Perl 的面向对象和模块结构特征。这让我很难相信他对现代工程界常用的脚本语言有多少了解。
            ```
            其实从功能上来说“脚本语言”望文生义的说法反而不对,至少很多python和perl“脚本”早就不算是什么“脚本”了。这方面站在工程角度都没法自圆其说。
            从一般使用方式来看,和Scheme这样王垠所谓严肃的(具有REPL的)语言一样,不管是python还是shell还是awk什么的,正经的说法大概都该叫“shell语言”。然而叵耐POSIX shell占着茅坑把shell这个概念也搞臭了,所以别的语言也不怎么好意思叫shell了……
            (其实explorer.exe还叫shell呢。UNIX厨你们颤抖了吗……)


            IP属地:北京10楼2015-05-30 09:04
            收起回复
              主菜。没错,日常挂GvR。
              ```
              那么,王垠的见解「深刻」么?我记得王垠曾经在一篇 blog 中《程序语言的常见设计错误(2)》用没有头和多长手批评 Python 语言设计允许每个对象随意添加删除属性。他说「然而你没有想到的是,由于 Python 提供的这种“描述世界的能力”,其它写代码的人制造出各种你想都没想到的怪人。」但是,这真的是程序语言的设计者没有想到的么?恐怕不是,比如这个:Strong versus Weak Typing。Guido 已经解释过,隐式的接口是 Python 的设计目标之一。而王垠批评这个特性最直接的动因,则是他自己说的:「在设计这个静态分析的时候,我发现 Python 的设计让静态分析异常的困难,Python 的程序出了问题很难找到错误的所在,Python 程序的执行速度比大部分程序语言都要慢,这其实是源自 Python 本身的设计问题。」换言之,这个特性让他不满,是因为这个特性让他很难设计静态分析器,虽然他马上将理由引到语言的所谓「设计问题」上。
              ```
              回答里的链接:http://www.artima.com/intv/strongweak.html
              不知怎么来着,每次一引用GvR的by design论点,都会让我觉得他是偏执狂+外行(这里除了王垠应该也有很多人黑),都快和James Gosling并列了。
              首当其中,GvR作为标榜“通用”语言的设计者,如果真内行,就该明白所谓Strong/Weak根本就是伪命题——因为这两个修饰type system性质的词早在数十年前(反正我记得比这篇引文的时间还要早很多)就因为理解混乱臭掉了,而且比“脚本语言”这种概念混乱程度还严重得多——内行之间背景稍微不同就可能总是鸡同鸭讲——而不只是外行理解正不正确的问题。
              对历史名词原意的曲解先不论,总之概念混乱已经是既定事实并且有人明确指出根本没法指望搞清楚是什么意思(仍然详见英文喂鸡)。所以在访谈中放任莫名其妙的概念忽悠大众,就有理由扣外行充内行+装的帽子。
              然后,看看引文吧。
              ```
              Bill Venners: I once asked James Gosling about programmer productivity. His answer, which I consider to be the strong-typers view of weak typing, was, "There's a folk theorem out there that systems with very loose typing are very easy to build prototypes with. That may be true. But the leap from a prototype built that way to a real industrial-strength system is pretty vast."
              real industrial-strength呵呵呵呵呵……然而暂时懒得挂JG……忍了不跑题。
              Bill Venners: Gosling also said, "Anything that tells you about a mistake earlier not only makes things more reliable because you find the bugs, but the time you don't spend hunting bugs is time you can spend doing something else." When I asked Josh Bloch about strong and weak typing, he said, "It's always beneficial to detect programming errors as quickly as possible."
              Guido van Rossum: Of course. I'm not arguing with that.
              ```
              GvR在这里似乎萎了(不知是不学无术还是单纯懒得说)。这里提问者的说法不管在PLT还是工程上都明显是有问题的:
              1.It's always beneficial to detect programming errors as quickly as possible.和这里所说的strong/weak typeing没有直接联系:不管是strong还是weak,和type checking的时机完全两码事。
              2.还真不可能是always。要fail fast算是常见现实需求之一,但是在所谓programming errors的外延都容易鸡同鸭讲(许多语言的用户往往对什么错误改谁负责没概念,再加上该用什么错误处理方式也很混乱)的情况下,一股脑尽量早发现问题不可能是理想状况。即便没有这种逗比现状,难道只管发现不管分散解决造成复用困难和花费的额外成本?更别说可行性了。
              ```
              Bill Venners: Josh Bloch continued, "There's no doubt that you can prototype more quickly in an environment that lets you get away with murder at compile time, but I do think the resulting programs are less robust. I think that to get the most robust programs, you want to do as much static type checking as possible."
              That all sounds fine to me in theory. It makes sense that the sooner I find programming errors the better. Strong typing helps me find errors at compile time. Weak typing makes me wait until a runtime exception is thrown. The trouble is that I use Mailman, a mailing list manager written completely in Python. Mailman works fine. It isn't a prototype. It's an application, and it seems quite robust to me. So where does theory miss practice?
              Guido van Rossum: That attitude sounds like the classic thing I've always heard from strong-typing proponents. The one thing that troubles me is that all the focus is on the strong typing, as if once your program is type correct, it has no bugs left. Strong typing catches many bugs, but it also makes you focus too much on getting the types right and not enough on getting the rest of the program correct.
              ```
              提问的观点其实大致上没错(虽然实际上需要取舍),而GvR却致命地把static typing和explicit/manifest typing混为一谈了。
              这里的错误就像Java厨因为打字少看着不安心或者Rob Pike觉得“类型就是分类”之类的理由拒绝引入type inference一样可笑。虽然Java厨是有意无视而且GvR和Java厨在打字多少的问题上针锋相对,然而无知程度是共通的。
              ```
              All that attention to getting the types right doesn't necessarily mean you don't have other bugs in your program. A type is a narrow piece of information about your data. When you look at large programs that deal with a lot of strong typing, you see that many words are spent working around strong typing.
              ```
              理论上其实有不符合“narrow piece”的情况。只不过这种字面上的这种系统的实用拙计连王垠都看不下去……
              不过以现在的角度来看,还是有些新的进展,比如unisonweb.org。照顾某些人可怜的想象力不展开了。
              ```
              The container problem is one issue. It's difficult in a language without generics to write a container implementation that isn't limited to a particular type. And all the strong typing goes out the door the moment you say, "Well, we're just going to write a container of Objects, and you'll have to cast them back to whatever type they really are once you start using them." That means you have even more finger typing, because of all those casts. And you don't have the helpful support of the type system while you're inside your container implementation.
              Python doesn't require you to write the cast, and its containers are completely generic. So it has the plus side of generic containers without the downside. It doesn't have the plus side that the C++ folks claim to get with their templates and other generics. But in practice that mechanism turns out to be very cumbersome. Even compiler writers have difficulty getting templates to work correctly and efficiently, and the programmers certainly seem to have a lot of trouble learning how to use it correctly. Templates are a whole new language that has enormous complexity.
              ```
              这里充分暴露了GvR对当时存在的类型系统的理解存在很大欠缺。generics只是避免显式转型的做法之一。(话说Java那时候有伪劣泛型了么……)不管怎么说,C++无视泛型的残废协变是98年就有的事。
              (这里要是顺势黑C艹我倒可能还会支持,然而既然没黑那就算了……)


              IP属地:北京11楼2015-05-30 09:39
              回复
                点心。
                ```
                王垠有没有水平?当然是有的,不然也就不会有他那 40 行代码。但是请不要忘记,CPS 变换并不是程序分析的全部手段,而仅仅是其中的一种,用于发现更多的优化机会。换句话说,我不会因为那代码写得好(说句公道话,我自己确实写不出来),而认为他对整个程序分析领域的所有看法都有道理。而从前面 Python 的例子,我们不难看出,王垠对事物的评判完全是以他自己为中心作出的。语言特性中能方便他的算法分析的就是好的语言设计,不能方便计算的就是糟糕的。但这恰恰是程序分析世界的大忌。
                ```
                对动态类型检查不爽,并不是王垠个人的意见;而这种设计造成程序低效也并没有问题。所以“我们不难看出,王垠对事物的评判完全是以他自己为中心作出的”从这里看还真没啥说服力——尽管我原则上不反对这个论点。
                ```
                静态分析的目标永远是帮助程序员理解语言,而不是证明自己的理论有多好。所以我们才会引入各种算法,变换程序形式。
                ```
                至少前半句是工程上的错误。在绝大多数条件下,照顾不照顾程序员本身充其量只是问题求解过程的一部分,程序员的需求——诸如降低智商需求,对无知容错——是得让位于boss和最终用户需求的。如果后者有变,程序员能说啥?
                说“静态分析的目标永远是帮助程序员理解”,那是把程序员永远当最终用户而不是自律的生产者看了——好像谁理解不了就不能开工了一样。绝大部分现实情况是,玩不起的一边去,谁行谁上。
                最重要的反例之一:“引入各种算法,变换程序形式”的优化编译器本身就是设计为不打算被大多数程序员理解的玩意儿(搞得用户都要理解,成本太高)。有意无意依赖特定编译器的特定行为而不是高级语言提供的接口,在工程实践上一般被认为是不好的习惯。
                ```
                说句不客气的话,王垠的「正确认识」,恰恰是建立在这些前辈的弯路上。站在我们现在的知识高度上,取笑他们缺乏远见,这已经不仅仅是一个礼貌的问题;在我看来,这也隐隐地显示出王垠恐怕早已失去了在研究领域中持续探索的动力。而后来所谓 yin 语言转入不公开开发的声明,更让我加深了这样的印象,就是「浮」。
                ```
                然而王垠已经多次表示过一些愚蠢的错误他从来就不犯……比如婊Coverity的那篇。
                把走弯路当作光荣,还真是微妙地没有说服力。另外,“我们”也自然不可能是铁板一块——王垠早年有文章指出过一大串“应该尊敬”的名单,看起来阶级界限还是挺清楚的。


                IP属地:北京13楼2015-05-30 10:12
                回复
                  http://my.oschina.net/chai2010/blog/118105
                  这年头Go厨都能嘴硬招摇了。
                  没啥威胁挤不进列表懒得开主题所以扔这。ID没存在感,不过观点可以抓典型婊。
                  正好通篇是槽点就省了全文引用了。
                  (说实话要不是今天@SunnyCase 洗逗比static我还记不起这货。)
                  ```
                  其实C++的构造函数差不多是个鸡肋: 用处不多, 但是却导致了有些不方便的地方.
                  ```
                  用处不多?避免去掉以后八成就逗比成C那鸟样(要边界没边界,该隐藏的墨迹半天没法复用,重构抽象出资源还得看码品),这种用处还要教?
                  不方便在哪下文一点都没点到,看起来就是自己不会用导致的智硬。
                  这等智商当然就不强求区分初始化和赋值啥的blahblah了,以下略。
                  ```
                  如果再参考Go语言的defer语句, C++的析构函数也可以算是残废品了.
                  ```
                  直接挂评论:
                  本来我是不想在公共场所中鸟散播低智商的厨的。
                  不过既然是Go厨就多优待一下:你丫那个逗比defer能让嵌套块内的副作用不萎到函数调用边界不?
                  还扯什么“析构函数也可以算是残废品了”,defer给我实现自动unwinding stack艹出exception neutrality试试?反过来呢?哪个有能耐实现哪个?
                  自己智硬见识少,会用一个拙计货所以其它自己不会用的都是辣鸡,唯独不会反省自己的智商和想象力,呵呵呵……
                  ```
                  构造函数可以用一个普通函数代替(当然值容器也要改变使用方式).
                  ```
                  然后编译器能脑补你使用哪个函数干什么破事?
                  ```
                  比如我们可以这样将C语言的FILE对象封装为类的形式(inline方式):
                  ```
                  inline都能成什么方式了……
                  ```
                  // 采用C++封装C语言的FILE(inline)
                  // MyFile指针运行时完全等价FILE指针
                  struct MyFile {
                  static MyFile* Open(const char* fname, const char* mode) {
                  return (MyFile*)fopen(fname, mode);
                  }
                  inline void Close() {
                  fclose((FILE*)this);
                  }
                  inline int Printf(const char * format, ...) {
                  return fprintf((FILE*)this, format, ...);
                  }
                  inline int Scanf(const char * format, ...) {
                  return fscanf((FILE*)this, format, ...);
                  }
                  private:
                  MyFile();
                  ~MyFile();
                  };
                  ```
                  等价FILE*有个球用?难道能多出原来没有的什么功能还是省事?
                  连自动释放资源都没有还要多此一举,用户特么凭什么不直接用<cstdio>里的函数要鸟这种裹脚布,增加阅读维护成本和误用机会?
                  C厨都不会那么傻造这种没品烂轮子。
                  ```
                  需要注意的是, Open返回的虽然是FILE指针, 但是被强制转换为MyFile类的this指针了.
                  ```
                  一提什么“强制”(coercion)大概就是谭×隔代门生……算了这个另外挂无所谓。
                  又是不靠谱的多此一举。
                  ```
                  以C语言的角度看, MyFile和FILE是完全等价的.
                  ```
                  C语言哪条规则保证什么“完全等价”?滚回去重修C(就这种拙计水平回炉以后最好也不要生产辣鸡C代码祸害reviewer)。
                  ```
                  而且没有了构造函数, 也便于接口和实现的分离:
                  // MyObject.h
                  struct MyObject {
                  // 构造对象
                  static MyObject* New();
                  // 释放对象
                  virtual void Delete()=0;
                  // funxxx
                  virtual void FunXXX()=0;
                  protected:
                  MyObject(){}
                  virtual ~MyObject(){}
                  };
                  // MyObject.cpp
                  namespace {
                  struct MyObjectImpl: public MyObject {
                  // ...
                  }
                  }
                  MyObject* MyObject::New() {
                  return new MyObjectImpl();
                  }
                  然后再结合前面提到的 C++版的defer语句 就可以实现类似 MutexLocker 之类的功能了.
                  当然, 因为C++没有GC, 复杂环境下对象的生命周期管理还是比较麻烦的.
                  ```
                  什么逗比分离,分离出了什么毛线?一个弱智制造资源泄漏机会的static New方法?剩下还有什么可用性?
                  所以之前评论:
                  这年头居然还有无视所有权直接返回内建指针的逗比还好意思扯什么分离……
                  难怪有“没有GC……生命周期管理还是比较麻烦”的奇葩结论。活该。
                  结果还敢嘴硬……
                  居然还会unnamed namespace,那要隐藏实现怎么不会直接不放头文件?这种智硬还好意思拿C代码出来……
                  分离出个problem factory半成品居然好意思叫分离,这种就是来找挂的……
                  这段玩意儿的语文水准看来也成问题,所以就不指望“没有了构造函数”“因为C++没有GC”跟这些二货逻辑跟紧接的下文有什么联系了。
                  对GC和一些其它反面的教材若干年前就已经挂过了,废话略。
                  再吊打一遍defer:当年AA还有那谁的scope guard,不知比这种山炮高哪里去了……(虽然我还懒得谈笑风生。)


                  IP属地:北京14楼2015-06-07 21:13
                  回复
                    等价FILE*有个球用?难道能多出原来没有的什么功能还是省事?
                    连自动释放资源都没有还要多此一举,用户特么凭什么不直接用<cstdio>里的函数要鸟这种裹脚布,增加阅读维护成本和误用机会?
                    C厨都不会那么傻造这种没品烂轮子。
                    23333333333333


                    IP属地:广西15楼2015-07-29 15:04
                    回复
                      "一提什么“强制”(coercion)大概就是谭×隔代门生……"
                      表示膝盖中了一箭.. 瞬间成了隔代..
                      自行搜索了下
                      引自stackoverflow:
                      The word conversion refers to either implicitly or explicitly changing a value from one data type to another, e.g. a 16-bit integer to a 32-bit integer.
                      The word coercion is used to denote an implicit conversion.
                      The word cast typically refers to an explicit type conversion (as opposed to an implicit conversion), regardless of whether this is a re-interpretation of a bit-pattern or a real conversion.
                      So, coercion is implicit, cast is explicit, and conversion is any of them.
                      /// 原文还引用了wiki来着..网址不贴了。
                      那么也就是说,强制(coercion)其实是隐式转换( implicit conversion) ?
                      且与自动类型转换(automatic type conversion)同一个意思吗?
                      先前不知道会与coercion冲突,一直把 强制转换或显式转换 理解成一个意思了,
                      说起来 “强制转换”可能是掺杂了个人的"通俗"理解:强制(手动进行)转换 的简称?
                      而英文则意指 不受用户选择的自动?


                      16楼2015-07-29 23:45
                      收起回复


                        IP属地:广东19楼2015-08-28 11:31
                        回复