Google 的 C++ 實驗性繼任者 Carbon 是否值得學習

語言: CN / TW / HK

自其誕生以來,C++ 一直是構建效能密集型應用程式的首選。但由於“委員會式設計 design by committee”,該語言仍有一些過時的做法。

2022年7月19日,在多倫多舉行的 CPP North C++ 會議上,Google 工程師 Chandler Carruth 介紹了 Carbon。

我們再來了解什麼是 Carbon 以及它打算如何取代 C++。

什麼是 Carbon?

Google 工程師開發了 Carbon 程式語言來解決 C++ 的缺點。

許多現有的語言,如 Golang 和 Rust 已經存在,它們反映了 C++ 的效能而沒有缺點。不幸的是,這些語言對現有 C++ 程式碼庫的遷移構成了重大障礙。

Carbon 的目標就像 TypeScript 之於 JavaScript, Kotlin 之於 Java。它不是一種替代語言,而是一種圍繞與 C++ 的互操作性而設計的繼承性語言。它的目標是對現有程式碼庫和開發人員進行大規模的採用和遷移。

Carbon 的主要特徵

Carbon 的一些關鍵特性包括 C++ 互操作性、現代泛型和記憶體安全。

與 C++ 的互操作性

Carbon 旨在為 C++ 開發人員提供一個溫和的學習曲線,並提供一套標準、一致的語言結構。

例如,以這個 C++ 程式碼為例:

// C++:
#include <math.h>
#include <iostream>
#include <span>
#include <vector>
 
struct Circle {
  float r;
};
 
void PrintTotalArea(std::span<Circle> circles) {
  float area = 0;
 
  for (const Circle& c : circles) {
    area += M_PI * c.r * c.r;
  }
 
  std::cout << "Total area: " << area << endl;
}
 
auto main(int argc, char** argv) ->; int {
  std::vector<Circle> circles = {{1.0}, {2.0}};
 
  // Implicitly constructs `span` from `vector`.
  PrintTotalArea(circles);
  return 0;
}

轉化為 Carbon,它變成:

// Carbon:
package Geometry api;
import Math;
 
class Circle {
  var r: f32;
}
 
fn PrintTotalArea(circles: Slice(Circle)) {
  var area: f32 = 0;
 
  for (c: Circle in circles) {
    area += Math.Pi * c.r * c.r;
  }
 
  Print("Total area: {0}", area);
}
 
fn Main() ->; i32 {
  // A dynamically sized array, like `std::vector`.
  var circles: Array(Circle) = ({.r = 1.0}, {.r = 2.0});
 
  // Implicitly constructs `Slice` from `Array`.
  PrintTotalArea(circles);
  return 0;
}

您還可以在應用程式中將單個 C++ 庫遷移到 Carbon,或在現有 C++ 程式碼之上新增新的 Carbon 程式碼。例如:

// C++ code used in both Carbon and C++:
struct Circle {
  float r;
};
 
// Carbon exposing a function for C++:
package Geometry api;
import Cpp library "circle.h";
import Math;
 
fn PrintTotalArea(circles: Slice(Cpp.Circle)) {
  var area: f32 = 0;
 
  for (c: Cpp.Circle in circles) {
    area += Math.Pi * c.r * c.r;
  }
 
  Print("Total area: {0}", area);
}
 
// C++ calling Carbon:
#include <vector>
#include "circle.h"
#include "geometry.carbon.h"
 
auto main(int argc, char** argv) ->; int {
  std::vector<Circle> circles = {{1.0}, {2.0}};
 
  // Carbon's `Slice` supports implicit construction from `std::vector`,
  // similar to `std::span`.
  Geometry::PrintTotalArea(circles);
  return 0;
}

現代泛型系統

Carbon 提供了一個帶有檢查定義的現代泛型系統。但它仍然支援可選模板以實現無縫 C++ 互操作性。

這個泛型系統為 C++ 模板提供了很多優勢:

  • 通用定義的型別檢查。這避免了為每個例項重新檢查定義的編譯時成本。
  • 強大、經過檢查的介面。這些減少了對實現細節的意外依賴,並建立了更明確的合同。

記憶體安全

Carbon 試圖通過以下方式解決記憶體安全問題,這是困擾 C++ 的一個關鍵問題:

  • 更好地跟蹤未初始化的狀態,增加初始化的執行,並加強初始化錯誤。
  • 設計基本 API 和習慣用法以支援除錯和強化構建中的動態邊界檢查。
  • 具有比 C++ 現有構建模式更全面的預設除錯構建模式。

開始使用 Carbon

您現在可以通過檢視程式碼庫並使用 Carbon explorer 來探索 Carbon:

# 使用 Homebrew 安裝 bazelisk
$ brew install bazelisk
 
# 使用 Homebrew 安裝 Clang/LLVM
# 許多Clang/LLVM版本並沒有使用我們所依賴的選項構建。
$ brew install llvm
$ export PATH="$(brew --prefix llvm)/bin:${PATH}"
 
# 下載 Carbon 程式碼
$ git clone https://github.com/carbon-language/carbon-lang
$ cd carbon-lang

# 構建並執行explorer。
$ bazel run //explorer -- ./explorer/testdata/print/format_only.carbon

Carbon 路線圖

根據 Carbon 路線圖,Google 將在 2022 年底之前釋出核心工作版本(0.1)來公開實驗。他們計劃在 2023 年釋出 0.2 版本,並在 2024-2025 年釋出完整的 1.0 版本。

Carbon 是否能夠複製 Golang 和 Kotlin 等其他語言的成功,還有待觀察。