前言:為什麼 C++ 總能引發激烈聖戰?
Linus Torvalds 曾言:「C++ 是一門有思想包袱的語言;為了讓程式設計師遠離 C++,我也要用 C。」這句話在社群引發巨大迴響,支持者與反對者各執一詞,觀望者無所適從。本文不討論語言優劣,而是從認知心理學角度剖析「語言之爭」背後的心理機制——自我服務偏見,幫助開發者建立理性技術決策框架。
核心現象:語言信仰與身份綁定
程式設計師投入大量時間掌握某語言 (C++ 尤甚),技能沉沒成本極高。當語言受質疑時,潛意識將其等同於**自我價值被否定**。心理學實證:
- 核武裝支持者遇誤報 → 認為「系統可靠」;反對者 → 認為「系統危險」
- 三哩島核洩漏 → 支持者視為「可控風險」;反對者視為「管理失敗」
- 同樣證據,因立場不同得出相反結論 —— 這就是自我服務偏見
程式語言社群 (C++、Java、Python、Rust…) 皆存在此現象:語言不再是工具,而是信仰。
理性思考的前提:擺脫偏見的三步法
- 承認沉沒成本:「我投入 N 年學 C++,但這不代表 C++ 適用於所有場景」
- 主動尋找反面證據:當看到支持觀點的論據時,強迫自己思考「有哪些證據不支持它?」
- 以專案需求為唯一準則:效能、團隊能力、生態成熟度、維護成本、招聘市場——而非語言特性清單
C++ 複雜性的真實面貌
複雜性來源三層剖析
| 層級 | 表現 | 本質 |
| 語法/語義 | 樣板元編程、SFINAE、ADL、參考摺疊、概念約束 | 靜態多型與零開銷抽象的代價 |
| 標準庫/慣用法 | 迭代器分類、分配器感知、執行策略、範圍視圖組合 | 演算法與資料結構解耦的泛型設計 |
| 系統/工程 | ABI 穩定、模組化編譯、跨平台建構、靜態/動態鏈結、除錯資訊 | 大規模軟體工程的現實約束 |
James Kanze 的洞見
「接觸 C++ 十年,仍需不時翻閱標準。」—— Eric Raymond 評價:「C++ 是反緊湊的。」細節多 ≠ 本質壞,關鍵在於:
- 是否建立「最小必要知識集」解決當前問題?
- 是否依賴工具 (編譯器警告、靜態分析、Sanitizers) 而非腦力記憶?
- 是否將複雜性封裝在庫/框架層,業務層保持簡潔?
工程決策框架:何時選 C++,何時避開?
✅ C++ 為最優選的場景
- 單機/分散式系統要求 微秒/納秒級延遲 (HFT、遊戲物理、即時渲染、信號處理)
- 記憶體/儲存/能耗極度受限 (嵌入式 MCU、衛星載荷、電池供電邊緣裝置)
- 需 直接操作硬體/核心介面 (驅動程式、虛擬化監視器、eBPF、韌體)
- 大型既有 C++ 代碼資產 (重寫成本 > 維護成本,Joel Spolsky 定律)
- 跨平台原生部署 (Windows/macOS/Linux/iOS/Android/WebAssembly 同一代碼庫)
❌ 應考慮替代語言的場景
- Web 後端業務邏輯 (Go/Java/C#/Node.js 開發效率碾壓)
- 資料科學/ML 原型 (Python 生態無可替代)
- GUI 桌面應用 (Qt/WPF/Electron/Tauri 皆有更高效選擇)
- 腳本/自動化/膠水代碼 (Python/Lua/Shell)
- 團隊缺乏 C++ 經驗且專案時程緊湊 (技術債風險極高)
給 C++ 從業者的建議
- 建立「核心 20%」知識體系:RAII、智慧指標、標準容器/演算法、移動語義、基本並發、模組/概念 —— 覆蓋 90% 日常開發
- 善用工具鏈防禦複雜性:
-Wall -Wextra -Wpedantic -Werror、Clang-Tidy、CppCoreGuidelines、AddressSanitizer/ThreadSanitizer/UB Sanitizer
- 封裝邊界清晰化:C API / COM / gRPC / WebAssembly 作為模組邊界,內部用現代 C++,外部見語言中性介面
- 持續重構而非大爆炸重寫:Strangler Fig 模式逐步現代化舊代碼
- 招聘考核聚焦工程素養:系統設計、除錯思維、效能分析、架構權衡 —— 而非語言冷門角落
總結
C++ 複雜,但複雜性服務於「零開銷抽象」與「硬體親和力」兩大核心價值。理性開發者不因信仰選語言,而是以問題域約束為錨點,在技術空間中尋找帕累托最優解。當你能平靜說出:「這專案用 Rust 更好,因為記憶體安全關鍵且無既有 C++ 資產;那專案用 C++ 更好,因為需直接呼叫驅動介面且團隊有經驗」——你就擺脫了偏見,成為真正的工程師。