為什么看到這么多人不推薦C++?
2000年左右是C++的鼎盛期,游戲,圖形界面,科學(xué)計(jì)算,后臺(tái)服務(wù),各種新語(yǔ)言的實(shí)現(xiàn)語(yǔ)言,甚至入侵了一點(diǎn)操作系統(tǒng)里C的地盤(pán)。
一項(xiàng)技術(shù),火起來(lái)蜂擁而上,泥沙俱下,平穩(wěn)后發(fā)現(xiàn)后勁不足,或者有另一個(gè)風(fēng)口出現(xiàn),便如樹(shù)倒萎潰散。
進(jìn)化是好事,進(jìn)化的同時(shí)要吸取經(jīng)驗(yàn),避免出現(xiàn)返祖現(xiàn)象。C++之父寫(xiě)過(guò)一本神書(shū),«C++語(yǔ)言的設(shè)計(jì)和演化»,鄙人孤陋寡聞,似乎這是唯一一本闡述語(yǔ)言設(shè)計(jì)理念、折衷的辛苦無(wú)奈歷程,Bjarne 在書(shū)中提出了很多極具智慧的設(shè)計(jì)理念,比如時(shí)下小火的儼然C++繼任者 Rust 也極為推崇的“零代價(jià)抽象”。
回到主題,為什么C++不再被推崇?客觀原因很明顯:
(1) C++語(yǔ)法很復(fù)雜,好的C++程序員難求。
語(yǔ)法上 C++14 開(kāi)始的“后現(xiàn)代C++”已經(jīng)改善不少,以前一些奇技淫巧可以拋棄了,但可惜為了向后兼容性,歷史包袱是丟不了的。
(2) 歷史上機(jī)器性能很弱,編譯器注重生成代碼效率而在不太注重警告語(yǔ)法陷阱——沒(méi)有足夠資源做分析,C++編譯已經(jīng)非常慢了,所以C++的開(kāi)發(fā)者友好度嚴(yán)重不足。
就像JS屆出了v8這個(gè)奇葩,C++屆有了LLVM后,逼得GCC也不斷改進(jìn),錯(cuò)誤信息提示友好漂亮多了,大微軟的VC編譯器還能把Effective C++, More Effective C++等書(shū)里描述的注意事項(xiàng)融入編譯器里,也是這個(gè)大微軟,開(kāi)源了好用的vcpkg,搭配CMake, C++的開(kāi)發(fā)體驗(yàn)比以前提升了很多,至少比 NodeJS 折騰一禮拜還不一定能搞定編譯工具鏈強(qiáng) 。
(3) Web 2.0 甚至 mobile web 時(shí)代,連老實(shí)賢惠的Java都被嫌棄,就別提C++了。
C++在科學(xué)計(jì)算的地位還是難以動(dòng)搖,別瞅現(xiàn)在Python火的紅屁股,其實(shí)就是個(gè)皮,沒(méi)有C/C++加持,Python屁都不是。
明確下觀點(diǎn):你不一定要用C++,但它值得了解。補(bǔ)一句,你不一定要用Rust,但它值得學(xué)習(xí)。
最后,貼一個(gè) Go 的例子,編譯沒(méi)問(wèn)題,運(yùn)行出錯(cuò),而在 C++ 里完全可以在編譯期就發(fā)現(xiàn)問(wèn)題,壓根不讓編譯通過(guò)。
- package main
- import (
- "fmt"
- "sync"
- "time"
- )
- func main() {
- var wg sync.WaitGroup
- wg.Add(1)
- go foo(wg)
- fmt.Println("before wait")
- wg.Wait()
- fmt.Println("after wait")
- }
- func foo(wg sync.WaitGroup) {
- fmt.Println("before sleep")
- time.Sleep(2 * time.Second)
- fmt.Println("after sleep")
- wg.Done()