• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當(dāng)自強(qiáng)而不息

            【ZT】神話(huà)與謬誤:爭(zhēng)論C++前你應(yīng)當(dāng)知道什么

            最近寫(xiě)了一篇關(guān)于C++0x Concepts的文章,意料之外地引起了一場(chǎng)小規(guī)模口水仗。回各位帖子的同時(shí),回想這些年C++社群的大小爭(zhēng)論,覺(jué)得有必要把一些長(zhǎng)久以來(lái)在C++爭(zhēng)論中出現(xiàn)的誤解列舉出來(lái)。

              …History became legend, legend became myth …- The Lord of the Rings

            哈雷將軍的笑話(huà)想必大家都聽(tīng)過(guò)。一句話(huà)經(jīng)口口相傳,每個(gè)人都根據(jù)自己的主觀意念加以潤(rùn)色,修補(bǔ),歪曲…到最后就面目全非。這里最關(guān)鍵的一環(huán)就是主觀意 識(shí),在歷史學(xué)里面有這么一句話(huà),大致意思是歷史其實(shí)只存在于人的意念之中;就算完全客觀的事件,通過(guò)不同的人的嘴說(shuō)出來(lái),造成的心理效應(yīng)也往往不一樣,每 個(gè)人都會(huì)加上那么一兩個(gè)形容詞,駕馭語(yǔ)言能力高的更是能夠舌綻蓮花,而語(yǔ)言本就有自身的力量,其中的遣詞造句對(duì)讀者構(gòu)成的心理影響力便應(yīng)運(yùn)而生。甚至于同 一句話(huà),用不同的語(yǔ)氣說(shuō)出來(lái),都會(huì)造成不同的效果。同一句話(huà),站在不同的立場(chǎng)上看,也會(huì)根本不是同一個(gè)意思。比如“C++還算是門(mén)不錯(cuò)的語(yǔ)言”,站在C+ +擁護(hù)者的角度聽(tīng)是在憐憫加詆毀C++,而站在C++反對(duì)者的角度聽(tīng)卻是抬舉了C++。

              在一個(gè)長(zhǎng)期被廣泛爭(zhēng)論的話(huà)題中,幾乎無(wú)可避 免的總是存在一些Fallacies和Myths。比如動(dòng)態(tài)&靜態(tài)類(lèi)型系統(tǒng)的爭(zhēng)論,據(jù)說(shuō)從圖靈時(shí)代就開(kāi)始了,到現(xiàn)在還有各種各樣的誤解,而且,可 以說(shuō),時(shí)間越長(zhǎng),系統(tǒng)內(nèi)的Fallacy越多。就連異常(exception)這樣不算復(fù)雜的語(yǔ)言特性里面居然也有一些長(zhǎng)期存在的誤解。

            至于這些Fallacies和Myths出現(xiàn)的原因很多:有人要“內(nèi)涵”唬人、有人要維護(hù)自己的心理優(yōu)勢(shì)、有人要維護(hù)自己的政權(quán)、有人要維護(hù)自己的利 益、有人因?yàn)樵?huà)從別人那里聽(tīng)了半句轉(zhuǎn)述給別人聽(tīng)的時(shí)候按主觀意念補(bǔ)全(誰(shuí)愿意說(shuō)“我不知道”呢?)、有人干脆就是人云亦云… 所以,一句話(huà),在一個(gè)靠口頭表達(dá)交換信息的社會(huì)中,F(xiàn)allacies和Myths是無(wú)處不在的,因?yàn)閺膬?nèi)心真實(shí)想法到外界表現(xiàn)出來(lái)的想法之間存在著“口 頭表達(dá)”這一中間層,后者由主觀意志支配。這里的中間層可不比軟件工程里面的間接層,在這個(gè)間接層上惡魔可以變成天使,天使也可以變成惡魔;六月飛雪可以 變成天降祥瑞,瓢潑大雨也可以變成艷陽(yáng)高照。Anyway,這展開(kāi)來(lái)就是一個(gè)心理學(xué)的問(wèn)題了,不多廢話(huà)了,有興趣的可以去看Harry G. Frankfurt寫(xiě)的《On Bullshit》或者Scott Berkun的這篇短文——“How to detect bullshit”。呃…我說(shuō)“一句話(huà)”了么?

              C++ - Fallacies and Myths

              C++作為一門(mén)被爭(zhēng)論不斷的語(yǔ)言,其中Fallacies和Myths自然不會(huì)少。一般來(lái)說(shuō),一個(gè)問(wèn)題在被大眾爭(zhēng)論中交換的話(huà)語(yǔ)數(shù)量與其中的Fallacy數(shù)量成正比。但一般來(lái)說(shuō)主要的Fallacies就那么幾個(gè):

              Fallacy #1 ——C++社群的哲學(xué)太學(xué)院派

            讓我們先對(duì)“學(xué)院派”下一個(gè)定義好不好?先問(wèn)你自己一個(gè)問(wèn)題,你心目中對(duì)“學(xué)院派”的定義是什么? 以下是一些選項(xiàng): 1. 傾向于理論美。2. 忽視實(shí)際編碼中的constraints(如效率,模塊性、可讀性等等)。3. 倡導(dǎo)語(yǔ)言律師行為。4. 鉆細(xì)節(jié)。5. … 我想如果我說(shuō)C++語(yǔ)言設(shè)計(jì)強(qiáng)調(diào)理論美,所有學(xué)過(guò)C++的人恐怕都會(huì)笑了…正如Bjarne自己所說(shuō)的,C++設(shè)計(jì)初期的Rule of Thumb之一便是“不要陷入到對(duì)完美性的固執(zhí)追求中”;不過(guò)具有諷刺意味的是,后面你會(huì)看到,正是這樣的一種哲學(xué)帶來(lái)了今天對(duì)C++的這個(gè)誤解。

            我猜持這樣一種觀點(diǎn)的人大多對(duì)于學(xué)院派的定義都是模糊的,一般都介于“提倡鉆語(yǔ)言細(xì)節(jié)并利用語(yǔ)言細(xì)節(jié)的做法”、“關(guān)注語(yǔ)言特性本身而忽略實(shí)際編碼需 求”、“對(duì)語(yǔ)言細(xì)節(jié)無(wú)休止的爭(zhēng)論”等等之間。 所以,當(dāng)有人說(shuō)“C++==學(xué)院派”的時(shí)候,他的真實(shí)意思很可能是:“C++語(yǔ)言的陰暗角落太多,而且C++社群還有提倡對(duì)語(yǔ)言角落把握的潛在哲學(xué),就連 C++0x的進(jìn)化也似乎更多關(guān)注語(yǔ)言特性,而那些語(yǔ)言特性根本就跟我們實(shí)際開(kāi)發(fā)者脫節(jié)了…”等等。 首先得承認(rèn)的是,在近一個(gè)十年的時(shí)間內(nèi),C++社群的確某種程度上建立起了一種對(duì)語(yǔ)言細(xì)節(jié)過(guò)分關(guān)注的心態(tài),這種心態(tài)毫無(wú)疑問(wèn)是錯(cuò)誤的,但只有知道這個(gè)錯(cuò)誤 是如何來(lái)的,才能解開(kāi)這個(gè)結(jié)。而且,就算一時(shí)解不開(kāi)這個(gè)結(jié),知道了原因之后才能保持理性的寬容態(tài)度,而不是亂發(fā)抱怨。一個(gè)理性的態(tài)度,更有助于良性發(fā)展。 例如如果C++社群都能明白這種潛哲學(xué)從何而來(lái),或許也就會(huì)漸漸走向更好的發(fā)展了。

              我用一個(gè)例子來(lái)說(shuō)明這一點(diǎn):你平時(shí)遍歷一個(gè)數(shù)組,或一個(gè)容器的時(shí)候是怎么做的?

            for(std::vector::iterator it = v.begin(); it != v.end(); ++it) {…} 這種做法很臃腫。其實(shí)你的邏輯是“對(duì)v中的每個(gè)元素,做…事情”,你知道大多數(shù)其它流行的語(yǔ)言中都有內(nèi)建的for_each。那C++中就沒(méi)有了嗎?有。 STL的for_each算法,于是你寫(xiě): struct MyOp{void operator()(int& i){…}}; std::for_each(v.begin(), v.end(), MyOp()); 這個(gè)方案實(shí)際很差。一是你還是得寫(xiě)v.begin()、v.end(),二是你得為此定義一整個(gè)新類(lèi)。三是這個(gè)新類(lèi)并不在你使用這個(gè)新類(lèi) (for_each被調(diào)用)的點(diǎn)上,因?yàn)榫植款?lèi)不能做模板參數(shù)。 你要的是lambda function: for_each(v.begin(), v.end(), <>(int& i){ …}); 可是C++98沒(méi)有。 你要的是內(nèi)建foreach: for(int& i : v) {…} 可是C++98沒(méi)有。

              鑒于循環(huán)結(jié)構(gòu)是編程中最常出現(xiàn)的結(jié)構(gòu)之一。這個(gè)問(wèn)題其實(shí)還是比 較惱人的,如果你覺(jué)得不惱人可能只是因?yàn)槟氵m應(yīng)性習(xí)慣了,這未必是好事。比如每次都要寫(xiě)std::vector::iterator就很讓人惱火,如果我 換個(gè)容器,就要修改一堆std::vector<…>。那用typedef行不行啊?行。可仍然還是需要寫(xiě)一次typedef,我很懶,我什 么多余的無(wú)用代碼都不想寫(xiě)。要知道,每多出一行無(wú)用的(并非因表達(dá)思想所需要才出現(xiàn))的代碼,就增加一點(diǎn)維護(hù)負(fù)擔(dān),這也正是為什么語(yǔ)言的表達(dá)力如此重要的 原因。

              那怎么辦?如果我告訴你,C++98里面其實(shí)你也可以寫(xiě): foreach(int& i , v){ …} 你怎么想? 廢話(huà)。當(dāng)然是求之不得了。有這么簡(jiǎn)潔的表達(dá)方式誰(shuí)還不想用啊。 我需要告訴你的另一個(gè)事實(shí)是。為了在C++98里面幾近完美地實(shí)現(xiàn)這個(gè)特性,有人把標(biāo)準(zhǔn)的角落挖了個(gè)底朝天。不,我不是在為鉆語(yǔ)言細(xì)節(jié)找理由,我只是想告 訴你,許多人所認(rèn)為的鉆語(yǔ)言細(xì)節(jié)的做法,其實(shí)一開(kāi)始大多是由用戶(hù)實(shí)際需求驅(qū)動(dòng)的,這個(gè)foreach設(shè)施被C++程序員們?cè)噲D實(shí)現(xiàn)了N遍N種做法,可見(jiàn)需 求之強(qiáng)烈。可惜絕大多數(shù)實(shí)現(xiàn)都遠(yuǎn)遠(yuǎn)稱(chēng)不上好用,就連現(xiàn)在這個(gè)實(shí)現(xiàn)的作者也早在03年在CUJ上發(fā)了一個(gè)實(shí)現(xiàn),也稱(chēng)不上好用。是后來(lái)又契而不舍才實(shí)現(xiàn)了最終 這個(gè)真正好用的版本的。 我想說(shuō)的是,上面這個(gè)美好的foreach,當(dāng)然人人都想用。但問(wèn)題是要在C++98下實(shí)現(xiàn)它只能靠挖標(biāo)準(zhǔn),這是唯一的途徑。要不然就得等語(yǔ)言進(jìn)化,并忍 受若干年,誰(shuí)愿意?況且這個(gè)foreach設(shè)施還能作占位符,在C++09來(lái)臨之前兢兢業(yè)業(yè)履行其職責(zé),C++09加入內(nèi)建foreach支持之后只消用 正則表達(dá)式搜索全局替換,就OK了,沒(méi)有任何的升級(jí)麻煩。

              再舉一個(gè)經(jīng)典的例子:STL里面的traits。其實(shí)traits不應(yīng)該是 traits。traits最自然的實(shí)現(xiàn)方式應(yīng)該是C++09的concept。但STL需要用到靜態(tài)dispatch技術(shù)啊,那怎么辦?要么用 traits(增加語(yǔ)言復(fù)雜性),要么不用(顯然不行)。

              再舉個(gè)經(jīng)典的例子:模板元編程。模板元編程有啥用?日常開(kāi)發(fā)者八輩子估計(jì)也用 不到。但真的嗎?沒(méi)錯(cuò),日常開(kāi)發(fā)者并不會(huì)直接用到。但是,由模板元編程支持的各個(gè)boost子庫(kù)呢?被選入C++0x的TR1的各個(gè)子庫(kù)呢(間接用到)? 那日常開(kāi)發(fā)者用不用學(xué)模板元編程呢?不用學(xué),根本不用學(xué),這么復(fù)雜的技術(shù)學(xué)什么呢?也就是點(diǎn)技巧上的東西。那為什么偏有人學(xué)呢?待會(huì)再說(shuō)。 還有大量的例子就不一一列了。其實(shí)STL的traits技術(shù)已經(jīng)能夠說(shuō)明問(wèn)題了。如果你仔細(xì)看一看,你會(huì)發(fā)現(xiàn),那些所謂的利用C++黑暗角落的技術(shù),幾乎 無(wú)一不是出現(xiàn)在庫(kù)開(kāi)發(fā)里面的,而之所以出現(xiàn)在庫(kù)開(kāi)發(fā)里面,是因?yàn)閹?kù)開(kāi)發(fā)中的需求驅(qū)動(dòng)的——為了開(kāi)發(fā)出更好的庫(kù)。難道你不想用更好的庫(kù)? 哦,說(shuō)到“更好的庫(kù)”,肯定會(huì)有同學(xué)有意見(jiàn)了。

              C++98都快十年了,標(biāo)準(zhǔn)庫(kù)還是只有那一套STL。庫(kù)進(jìn)展緩慢,到現(xiàn)在GUI庫(kù)也沒(méi)有一個(gè)標(biāo)準(zhǔn),都是四分五裂各自為營(yíng)。網(wǎng)絡(luò)庫(kù)也是、文件系統(tǒng)庫(kù)也是、日志庫(kù)也是…不過(guò)這個(gè)問(wèn)題已經(jīng)是另一個(gè)問(wèn)題了,容后再說(shuō)。

            問(wèn)題是,“沒(méi)有標(biāo)準(zhǔn)的庫(kù)”并不意味著“C++的庫(kù)不好”,后者也并不意味著“那些晦澀的技巧并沒(méi)有提升庫(kù)的質(zhì)量”,這個(gè)邏輯上的兩環(huán)都不對(duì)。實(shí)際上,人 們所謂的“晦澀而復(fù)雜的技巧”其實(shí)正是為了提升庫(kù)的質(zhì)量而被挖掘出來(lái)的。traits技術(shù)提升庫(kù)的效率(靜態(tài)轉(zhuǎn)發(fā)),type erase技術(shù)使得boost::function可以接受任何簽名為void()的函數(shù)(靈活性),包括仿函數(shù),包括boost::bind后的函數(shù)。 type list技術(shù)使得boost::tuple能夠接受可變數(shù)目的模板參數(shù)。policy-based design使得可以對(duì)一個(gè)設(shè)施的功能進(jìn)行正交分解… 就算把所有流行的C++ tricks都列出來(lái),你也會(huì)發(fā)現(xiàn),其實(shí)它們幾乎每一個(gè)都對(duì)應(yīng)了至少一個(gè)實(shí)際應(yīng)用。而實(shí)際應(yīng)用需求哪來(lái)的?庫(kù)設(shè)計(jì)的需求。但歸根到底,是使用庫(kù)的人——終 端程序員——的需求。(效率、靈活性、抽象表達(dá)力,哪一樣不是終端程序員的實(shí)際需求呢?)

              再舉個(gè)實(shí)例,有同學(xué)說(shuō),我只要寫(xiě)簡(jiǎn)單的代碼。問(wèn)題是,簡(jiǎn)單不意味著單純。簡(jiǎn)單意味著在更高抽象層次上面編程,后者是要靠好的庫(kù)抽象才能達(dá)到的。借用《Extended STL》里面的一個(gè)例子:

              DIR* dir = opendir(".");

              if(NULL != dir){

             struct dirent* de;

             for(; NULL != (de = readdir(dir)); )

             {

              struct stat st;

              if( 0 == stat(de->d_name, &st) &&S_IFREG == (st.st_mode &S_IFMT)) {

               remove(de->d_name);

              }

             }

             closedir(dir);} 這段代碼刪除當(dāng)前目錄中所有文件。

             readdir_sequence entries(".", readdir_sequence::files);

             std::for_each(entries.begin(), entries.end(), ::remove); 這段代碼做同樣的事情——哪個(gè)更簡(jiǎn)單?

            那問(wèn)題是,為什么發(fā)展到后來(lái),“鉆語(yǔ)言細(xì)節(jié)”成了社群的潛在哲學(xué)呢? 這其實(shí)是一個(gè)心理學(xué)上的問(wèn)題,跟語(yǔ)言沒(méi)有關(guān)系,跟C++的初衷更沒(méi)有關(guān)系。從心理上,在同一個(gè)領(lǐng)域,如果另一個(gè)人比你懂得更多,你就會(huì)傾向于佩服他,這時(shí) 另一個(gè)人懂的東西有多大的用處其實(shí)并不那么重要,人對(duì)自己不懂的東西總是有一種敬畏感的。

              C++里面有那么多的tricks,其實(shí)日常編程中要用到的trick少之又少,日常編程絕大多數(shù)都以復(fù)用庫(kù)為主,而那些tricks就隱藏在庫(kù)里面。除非你是庫(kù)的設(shè)計(jì)者,否則很多的tricks根本就無(wú)需關(guān)注。

            另一方面,寫(xiě)作C++書(shū)籍的大多數(shù)都是C++庫(kù)的設(shè)計(jì)者,這就給予了許多C++書(shū)一個(gè)有偏見(jiàn)的視角,大量庫(kù)設(shè)計(jì)中才會(huì)用到的技術(shù)被介紹出來(lái),而社群對(duì)這 些牛人又都是唯馬首是瞻的。(其實(shí)我覺(jué)得一本Bjarne的《The C++ Programming Language》加上一本Herb&Alexandrescu的《C++ Coding Standard》對(duì)于日常程序員來(lái)說(shuō),真的足夠了。)

            此外,人總是好奇的,在C++里面有那么多的被“發(fā)明”的好玩技術(shù),怎么可能不會(huì)有人去追捧呢。另一個(gè)動(dòng)機(jī)則是學(xué)了這些技術(shù)有立竿見(jiàn)影的炫耀效果,比如在 論壇上。這可比編寫(xiě)可維護(hù)代碼的才能容易表現(xiàn)多了——人自然是更傾向于去關(guān)注那些更容易拿來(lái)表現(xiàn)和炫耀的東西的。退一步說(shuō),就單單是“發(fā)明”一項(xiàng)新的語(yǔ)言 特性組合運(yùn)用技巧都能帶來(lái)純粹的成就感,因?yàn)槟阌衷诂F(xiàn)有語(yǔ)言框架下作出了一個(gè)創(chuàng)舉,你做了別人做不到的。而作為學(xué)習(xí)者,你可能會(huì)因?yàn)榘l(fā)現(xiàn)原來(lái)自己理解的一 塊土地上還有不知道的東西而感到興奮和新奇,這種興奮和新奇感往往是學(xué)習(xí)的真正原動(dòng)力。至少,對(duì)于我來(lái)說(shuō),當(dāng)年讀《Modern C++ Design》時(shí)正是這樣一種感覺(jué),我想有和我一樣感覺(jué)的人肯定不在少數(shù)。

              再來(lái),一個(gè)是在人前看不見(jiàn)摸不著的編碼能力,另一個(gè)是對(duì) handy的技巧的掌握。作為一個(gè)學(xué)習(xí)者,傾向于學(xué)習(xí)后者,因?yàn)楹笳邔W(xué)起來(lái)更容易,而且也往往更有趣。學(xué)到了之后能夠得到跟解決重大問(wèn)題同等的成就感—— 看看《Effective C++》系列受到的追捧就知道了。

              再來(lái),當(dāng)你面臨兩個(gè)問(wèn)題,一個(gè)是如何建立一個(gè)高質(zhì)量的庫(kù)(大),一個(gè)是如 何修正庫(kù)里面的小bug(如vector里面某個(gè)成員函數(shù)的異常保證問(wèn)題)。如果你有一份時(shí)間,你更傾向于把它花在什么地方?人在心理上總是傾向于走“捷 徑”的,體現(xiàn)在這個(gè)問(wèn)題上面便是更傾向于對(duì)付耍點(diǎn)小聰明就解決的小問(wèn)題,并獲得甚至并不亞于解決大問(wèn)題的成就感。小問(wèn)題的另一個(gè)吸引人的地方在于它耗時(shí) 短,更“趁手”,它不需要你閉關(guān)苦苦編碼幾個(gè)月弄出一個(gè)框架來(lái)而且還不一定能成。所以這就給人一種錯(cuò)覺(jué),C++社群只知道爭(zhēng)論枝節(jié)問(wèn)題,不知道實(shí)干庫(kù)。 哦,不是錯(cuò)覺(jué),這的確是大部分的現(xiàn)狀,但這個(gè)現(xiàn)象其實(shí)并不僅僅止于C++社群,這是人心理的共性造成的,這也就是為什么無(wú)論在哪個(gè)語(yǔ)言社群你都會(huì)看到爭(zhēng)論 最多的都是些“小問(wèn)題”的原因。(當(dāng)然,無(wú)論在哪個(gè)學(xué)科,也還總是有牛人去啃難啃的骨頭的。但這并不是廣大民眾的狀況。) 以上種種原因共同造就了C++社群的這種心態(tài)。

              這其實(shí)跟C++的“教義”沒(méi)有關(guān)系。C++如果有教義的話(huà)也是實(shí)用為上。這種現(xiàn)狀是自發(fā) 產(chǎn)生的,它的動(dòng)力來(lái)源于人的心理。如果Java語(yǔ)言有各種各樣的特性組合,且這些特性組合能夠某些時(shí)候滿(mǎn)足開(kāi)發(fā)中的實(shí)際需求的話(huà),也是一樣會(huì)出現(xiàn)這樣的情 況的(事實(shí)上一個(gè)小小的Java Closure就已經(jīng)引起了大量口水了)。某種程度上,LISP里面用函數(shù)來(lái)實(shí)現(xiàn)自然數(shù)系統(tǒng),也是一樣的道理,你敢說(shuō),你第一次看到它的時(shí)候,不驚嘆?人 之常情而已。 那這種哲學(xué)對(duì)不對(duì)?廢話(huà)。當(dāng)然不對(duì)。不但不對(duì),而且有害。很多C++日常開(kāi)發(fā)者在學(xué)習(xí)庫(kù)開(kāi)發(fā)技巧上浪費(fèi)了很多時(shí)間,掌握了根本用不到的技術(shù),而且這些技 術(shù),不如稱(chēng)為技巧,可能還會(huì)隨著語(yǔ)言進(jìn)化變得根本無(wú)用武之地。還不如好好學(xué)學(xué)如何讓自己的代碼更KISS呢,基本的編碼準(zhǔn)則要遠(yuǎn)遠(yuǎn)重要得多,正如我剛才說(shuō) 的,日常開(kāi)發(fā),一本《The C++ Programming Languag》加一本《C++ Coding Standard》足夠了。

              另外,說(shuō)到語(yǔ)言進(jìn)化順便說(shuō)一句,語(yǔ)言進(jìn)化的職責(zé)之一便是廢黜繁復(fù)的技巧,取代以直接表達(dá)思想的語(yǔ)言特性。而C++0x真正在履行這一職責(zé)。 最后來(lái)說(shuō)一說(shuō)前面留下來(lái)的一個(gè)問(wèn)題:為什么C++設(shè)計(jì)的初衷——“不要固執(zhí)于完美”——某種程度上帶來(lái)了這個(gè)局面呢?

            因?yàn)檎且驗(yàn)檫@種理念的指導(dǎo),有不少語(yǔ)言特性從理論上都是不完備的:比如有copy語(yǔ)意沒(méi)有move語(yǔ)意(有左值引用沒(méi)有右值引用),于是 Alexandrescu用Mojo框架來(lái)解決;比如支持可變參數(shù)的函數(shù)調(diào)用卻不支持可變參數(shù)的模板參數(shù)列表,導(dǎo)致用元編程來(lái)解決;比如不支持構(gòu)造函數(shù)轉(zhuǎn) 發(fā),導(dǎo)致必須factor出一個(gè)公共的initialize函數(shù)來(lái);比如不支持強(qiáng)類(lèi)型的enum,結(jié)果用一大堆宏結(jié)合類(lèi)來(lái)解決;比如不支持 initializer list,結(jié)果用復(fù)雜的模板技術(shù)來(lái)實(shí)現(xiàn)某種類(lèi)似的初始化方式;比如不支持auto和typeof,結(jié)果用更復(fù)雜N倍的模板元編程技術(shù)來(lái)實(shí)現(xiàn)一個(gè)模擬;比如 不支持內(nèi)建的alignment指示,導(dǎo)致Alexandrescu在實(shí)現(xiàn)類(lèi)型安全的union的時(shí)候用盡了模板元編程技巧;比如不支持內(nèi)建的 foreach,結(jié)果借助于詭異的語(yǔ)言角落實(shí)現(xiàn)了一個(gè)幾近完美的模擬;比如不支持內(nèi)建的concept,導(dǎo)致使用模板技巧來(lái)實(shí)現(xiàn)也算能用的concept 檢查…這個(gè)列表可以一再延長(zhǎng)下去,C++中這樣的示例太多了。C++的不完美導(dǎo)致了各種各樣的技巧應(yīng)運(yùn)而生,哦,不,應(yīng)該說(shuō),應(yīng)實(shí)際需求而生。這從另一個(gè) 側(cè)面正說(shuō)明了一點(diǎn)—— C++太需要進(jìn)化了!

              Fallacy #2 ——C++委員會(huì)過(guò)分關(guān)注一些不切實(shí)際的語(yǔ)言特性,而不關(guān)心標(biāo)準(zhǔn)庫(kù)的擴(kuò)充

            比起第一個(gè)fallacy來(lái),這個(gè)倒容易解釋清楚了。人家Bjarne在文章和訪談里面一再?gòu)?qiáng)調(diào),C++從來(lái)都是把庫(kù)設(shè)計(jì)放在首位的(這句話(huà)其實(shí)就意味 著,是把最終開(kāi)發(fā)者放在首位的——什么?你難道不用庫(kù)?),但是C++群體是一個(gè)分散多樣的群體,而且沒(méi)有大公司的財(cái)力支持。前者意味著眾口難調(diào)(標(biāo)準(zhǔn)化 過(guò)程困難),后者意味著不能集中精英的人力(boost庫(kù)的開(kāi)發(fā)都是由大家業(yè)余時(shí)間完成的)來(lái)搞出個(gè)百萬(wàn)美元的免費(fèi)庫(kù)來(lái)。此外個(gè)人用業(yè)余時(shí)間來(lái)開(kāi)發(fā)庫(kù)還意 味著往往沒(méi)有足夠的精力來(lái)對(duì)庫(kù)進(jìn)行精化改善,導(dǎo)致庫(kù)的質(zhì)量不佳或者干脆停滯(這樣的C++庫(kù)案例很多)。比如日志庫(kù)吧,沒(méi)有一打也有半打,但由于都是個(gè)人 業(yè)余開(kāi)發(fā),所以沒(méi)有精力做到盡善盡美,唯一一個(gè)往boost提交的是John Torjo(也是個(gè)牛人)寫(xiě)的,不過(guò)一年前被reject之后就沒(méi)了動(dòng)靜。你難道怪人家?人家又不是你雇來(lái)的。

              但說(shuō)到底,還是錢(qián)的問(wèn) 題,眾口難調(diào)還是終究能調(diào)的(boost發(fā)起的初衷便在于此)。但沒(méi)有錢(qián),鬼才跟你推磨呢。 不過(guò)好消息是據(jù)說(shuō)boost明年能拿到fund:-) 應(yīng)該能把boost狠狠boost一把。 至于“C++委員會(huì)過(guò)分關(guān)注一些不切實(shí)際的語(yǔ)言特性”就不知從何說(shuō)起了。首先,前文已經(jīng)明確說(shuō)明語(yǔ)言進(jìn)化的重要性以及實(shí)用性,這說(shuō)明語(yǔ)言進(jìn)化根本不像人們 認(rèn)為的那樣“不切實(shí)際”,而是與實(shí)用休戚相關(guān)的。其實(shí)從根本上,語(yǔ)言進(jìn)化就是為了帶來(lái)更好的庫(kù),以及更好的代碼(包括日常編碼),這一點(diǎn)跟大伙殷殷企盼著 標(biāo)準(zhǔn)庫(kù)其實(shí)并不相左。此外還有一點(diǎn)就是,討論語(yǔ)言特性比實(shí)際去開(kāi)發(fā)庫(kù)要花更少的精力,這兩者花的精力其實(shí)不在一個(gè)數(shù)量級(jí)上,開(kāi)發(fā)一個(gè)庫(kù)出來(lái)要難得多得多, 所以就造成了一種假象——“委員會(huì)的那幫家伙只知道倒騰語(yǔ)言”。這個(gè)論點(diǎn)錯(cuò)在了兩個(gè)地方,一,倒騰語(yǔ)言是必要的。二,他們并非只知道倒騰語(yǔ)言,只是庫(kù)的問(wèn) 題要艱難得多,沒(méi)錢(qián),人家難道砸鍋賣(mài)鐵給你開(kāi)發(fā)標(biāo)準(zhǔn)庫(kù)嗎?

              有同學(xué)說(shuō),我只要一個(gè)能用的庫(kù)就行了。但問(wèn)題是,標(biāo)準(zhǔn)庫(kù)能隨便嗎?標(biāo)準(zhǔn)庫(kù)之所 以不能隨便,是因?yàn)橄襁@樣受眾極其廣泛的庫(kù)可是要負(fù)責(zé)任的——將會(huì)有百萬(wàn)千萬(wàn)行代碼都依賴(lài)它。如果標(biāo)準(zhǔn)庫(kù)里面有bug,將會(huì)出現(xiàn)幾百萬(wàn)上千萬(wàn)行 workarounds,這些workarounds依賴(lài)于庫(kù)的bug,為了保持向后兼容性,標(biāo)準(zhǔn)庫(kù)甚至都不能修正這些bug。就連STL這樣漂亮的抽 象,迭代器區(qū)間還是闖了禍。另一方面,如果只是需要一個(gè)能用的庫(kù),C++社區(qū)有大量“能用”的庫(kù)。姑且不說(shuō)boost里面的了。

              Fallacy #3 ——C++的強(qiáng)處在于什么都能做

            一個(gè)最常見(jiàn)的論調(diào)就是,java的虛擬機(jī)也是C++做的,于是得出結(jié)論,java比C++弱,java沒(méi)有C++好。 姑且不說(shuō)“好”的定義標(biāo)準(zhǔn)是什么。就算java的虛擬機(jī)做的,那C++的第一個(gè)編譯器還要用C寫(xiě)呢。C庫(kù)里面的某些成分還要用匯編寫(xiě)呢。這個(gè)論據(jù)是站不住 腳的。 其實(shí),持這種論點(diǎn)的人是站錯(cuò)了位置,問(wèn)錯(cuò)了問(wèn)題。

              關(guān)鍵的問(wèn)題不是一門(mén)語(yǔ)言能做什么,因?yàn)檎f(shuō)到能做什么,匯編什么都能做。而是 “在某個(gè)特定的領(lǐng)域,哪門(mén)語(yǔ)言表現(xiàn)更好”,人們的需求幾乎總是對(duì)著某個(gè)特定的領(lǐng)域的。后者才是真正matter的問(wèn)題。 從這個(gè)角度看,C++的市場(chǎng)其實(shí)只在效率這一塊。有人可能會(huì)說(shuō),那效率這一塊有C啊。問(wèn)題是,C的抽象機(jī)制太弱。寫(xiě)架構(gòu)簡(jiǎn)單的應(yīng)用,或者寫(xiě)一些核心的(如 驅(qū)動(dòng)程序),沒(méi)有面向?qū)ο蠼Y(jié)構(gòu)的程序,容易。完全可以用C。但涉及到大型系統(tǒng),比如.NET基層架構(gòu),一些3D游戲。必須用到面向?qū)ο蠡蚧趯?duì)象編程的領(lǐng) 域,C在代碼組織和抽象方面的弱點(diǎn)就暴露出來(lái)了。比如用C和宏來(lái)實(shí)現(xiàn)所謂OO,就正說(shuō)明了C的抽象機(jī)制的薄弱。

              但是,C++的領(lǐng)土 基本也就在這些地方了。簡(jiǎn)而言之就是所有“效率重要,且同時(shí)需要好的抽象機(jī)制的應(yīng)用領(lǐng)域”。因?yàn)镃++的優(yōu)勢(shì)就是無(wú)損效率的實(shí)現(xiàn)更好的抽象。 那C++既有效率又有更好的抽象機(jī)制,為什么C++不能取代java、不能取代python,不能取代ruby?或者至少當(dāng)C++進(jìn)化到更好的階段的時(shí) 候,比如C++0x就是一個(gè)大的進(jìn)展(在語(yǔ)言方面),為什么作為一門(mén)語(yǔ)言,不能取代那些嚴(yán)重“偏科”的語(yǔ)言呢?

              原因有兩方面。一方面, 正因?yàn)?#8220;偏科”,所以有些語(yǔ)言才能在它們擅長(zhǎng)的領(lǐng)域做得更好,乃至做到最好。“偏執(zhí)狂才能生存”。人們的需求幾乎總是在特定領(lǐng)域的,你說(shuō)這時(shí)候人是愿意選 用一門(mén)專(zhuān)門(mén)為這個(gè)領(lǐng)域而生的語(yǔ)言(ruby),還是愿意用一門(mén)general-purpose的語(yǔ)言(C++)?另一方面,就算C++在抽象機(jī)制上進(jìn)化到 了非常好,乃至于能在某些特定領(lǐng)域也表現(xiàn)不菲的話(huà),由于市場(chǎng)早就被別的語(yǔ)言侵占,別的語(yǔ)言已經(jīng)有了成百上千萬(wàn)行的代碼基,別的語(yǔ)言的庫(kù)已經(jīng)發(fā)展到非常豐富 的程度,別的語(yǔ)言的相關(guān)人才教育已經(jīng)一代又一代,所以結(jié)果還是沒(méi)得拼。 其實(shí),從另一個(gè)角度來(lái)說(shuō),C++何嘗不也是一門(mén)偏執(zhí)的語(yǔ)言呢?C++的偏執(zhí)就是效率,C的偏執(zhí)也是效率,但C++提供更好的抽象,因此在這一塊(效率+抽 象),C++比C有優(yōu)勢(shì)。 C++的領(lǐng)土已經(jīng)鑄成,另一方面,C++的領(lǐng)土在可見(jiàn)的未來(lái)也不大可能縮水了。這是C++的現(xiàn)實(shí),這個(gè)現(xiàn)實(shí),至少在Bjarne看來(lái),也沒(méi)什么不好,因?yàn)? 它正反映了C++當(dāng)時(shí)設(shè)計(jì)的意圖——更好的C。我們也不用趕鴨子上架,非拿C++和其它語(yǔ)言比——適用的場(chǎng)合本就不同,沒(méi)得比。 Fallacy #4 …

              事不過(guò)三,就此打住。況且,這三條難道還不夠嗎?如果你想到還有什么fallacy要補(bǔ)充的,請(qǐng)不吝回帖:) 我會(huì)考慮加到文章里面的:)


            posted on 2007-10-12 09:43 lovedday 閱讀(577) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): ▲ C++ Program

            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(lèi)(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評(píng)論

            AV无码久久久久不卡网站下载| 久久久久久噜噜精品免费直播| 久久精品国产亚洲AV久| 亚洲国产精品无码久久久蜜芽| 久久精品国产亚洲77777| 久久最新精品国产| 亚洲伊人久久综合影院| 午夜天堂精品久久久久| 国产精品久久久天天影视香蕉| 香蕉久久永久视频| 97久久久久人妻精品专区| 久久免费香蕉视频| 97久久久久人妻精品专区| 欧美麻豆久久久久久中文| 久久精品国产亚洲av影院| 国产精品一区二区久久精品涩爱| 99久久无码一区人妻a黑| 国产成人综合久久精品红| 亚洲国产天堂久久综合网站| 7777精品久久久大香线蕉| 精品久久久久久无码中文字幕| 亚洲AV无码久久寂寞少妇| 中文字幕无码av激情不卡久久| 久久久久中文字幕| 国产精品99久久精品| 天天躁日日躁狠狠久久| 免费一级欧美大片久久网| 狠狠人妻久久久久久综合蜜桃| 久久国产亚洲高清观看| 伊人久久大香线蕉综合Av| 亚洲成av人片不卡无码久久| 久久影院亚洲一区| 久久精品综合一区二区三区| 久久精品亚洲男人的天堂| 精品久久久久久无码中文野结衣| 91精品国产综合久久香蕉| 日本三级久久网| 久久精品国产99久久久香蕉| 国产精品久久久久一区二区三区 | 久久久久99精品成人片欧美| 久久精品国产2020|