Introduction

  • JavaScript → TypeScript
  • Java → Kotlin
  • C++ → Carbon

Note that Carbon is not ready for use.

Carbon: 完美的C++接班人

Carbon,下一个 C++ 挑战者?

增加图片注释,不超过 140 字(可选)

最近,Google向社区奉献了一个全新的言语——Carbon,并且兴致勃勃的想要做新时代的C++接班人!

github.com/carbon-lang…

Related Work

C++

众所周知,c++ 应用广泛,许多功用灵敏的软件和体系在构建时都会优先考虑c++,它在诞生之初也是一个单方面兼容C(C的超集)的高档言语。这也带来了许多弊病,许多大型的代码基础库也都是积年累月几代猿猴用cpp 煞费苦心编写而成。从c++11 开端,大多数程序猿终于摆脱了c with class 的印象派写法。可是关于没写几年cpp的程序猿来说,运用cpp的一些底子性问题仍然存在:

  • ABI 问题
  • 当你用一个库,里边必定存着许多信息(比如实际的机器码、函数表),总得有一个规定阐明他们存储的结构(PE/dll,elf/so),这便是ABI的一部分。
  • 当你想用库里的一个函数,你总得去查找函数表。可是关于C++,并不是存函数名就够的。C++答应重载,即两个函数可以同名但不同参数,所以要把参数信息一起编码进去才能进行查找,这个便是name mangling。
  • 此外,不同的架构(如x86和arm,x86的32位/64位)有着不同的资源/寄存器,也会导致calling convension的不同。相互之间机器码不能互相兼容,所以也要纳入ABI的考量。
  • 一般开源库都供给源码,无法用binary方法发布,且一般强制运用c的ABI来给其他调用者运用
  • 体系库功用问题

规范库功用堪忧,功用不全,需要引进三方库或许自己手撸来补齐才能

  • 反常不可用
  • 各个toolchain 以及厂商之间的完成导致反常处理并不一致,没有放之四海而皆准的反常捕获方法。只能弃用反常,任由程序张狂中止。
  • 没有一个一致成熟的包管理机制

可是瑕不掩瑜,c++ 超高的功用、超强的拓宽性又让人骑虎难下。

为了躲避c++ 由于过于自由而产生的安全性问题,Rust 应运而生。

Rust

Advantages

  • 零本钱笼统

即我运用到的特性,我“付费”,我没有运用的特性,跟我也不要紧。

  • 类型安全与内存安全

Rust通过强大的类型体系和所有权模型来确保内存安全与线程安全,在编译时消除许多或许存在的过错。

Rust里每一个引证和指针都有一个lifetime,目标则只不答应在同一时间有两个和两个以上的可变引证。

运用Rust言语编程不需要手动分配(malloc)开释(free)内存和资源。Rust通过所有权体系来判断资源分配和开释的时机,在资源不再运用主动调用析构函数并开释资源。(这里看起来其实和C++的RAII相同,也是C++精髓所在)所有权体系是Rust与其他言语最不同的一点,这也是Rust学习曲线较为峻峭的原因之一。

  • Rust运用特征(trait)机制来完成笼统和代码复用
  • 包管理 Cargo

Disadvantages

心智担负高,通过编写代码时的规约来束缚程序的行为,透过编译器来束缚代码边界。Rust 适合新项目,很难与原始的c++项目无担负的混编

Carbon

Google 推出的 Carbon 旨在像在android 项目中运用kotlin 替换 java,像在前端项目顶用TS替换JS相同,迁移的本钱小,兼容老代码,运用新特性。c++关于开发者的要求实在是太高了,除了c++之父,简直没人敢说自己精通Cpp,无论是模板套模板能把人绕晕,仍是析构之后四处溃散的变量。让人始终不能专注于事务的开发与拓宽,当然这也是高功用言语的魅力。Carbon 的诞生主要是由于Google 在 c++规范委员会里四处碰壁,有关协程以及其他相关的提案日常被否。所以Google 爽性另起炉灶,自己构建了一个号称c++继任者——Carbon,号称既能确保高功用,又能跟C++在同一文件中混编,还让开发者没有那么高的心智担负。十分适合一些陈年迈项目的迁移。当然,现在它还处于相对不完善的状况,我们来看看它的任务愿景和一些相关的探究

  • 功用对标C++
  • 与 C++ 的无缝、双向互操作性,因而现有 C++ 堆栈中的任何库都可以采用 Carbon,而无需移植其余部分。
  • 不那么峻峭的学习曲线
  • 同样可以对地址进行low level的拜访
  • 更高的安全性,更强的包管理机制

这个无缝双向互操作性其实便是针对cpp 的头文件生成AST(笼统语法树),遍历一遍,然后对应的在Carbon也生成一份对应的 Carbon AST,然后其他的就都交给clang,帮我们做好所有烦心的工作。

Safety

其实看起来,如同也便是简化版C++,可是,汲取了Rust 的相关经验,Carbon 在言语层面的安全性上也做了一些设计

  • 内存安全:不答应越界拜访,撤销null指针,撤销未初始化的指针,制止拜访已经开释的地址
  • 类型安全:不答应用不正确的类型来拜访有效的内存
  • 数据竞争安全:避免多个线程在没有“同步”的情况下对内存地址进行读写

也便是说,在编译阶段,就通过编译器来束缚代码的行为,将人类的先验知识,用编译器行为来表达出来,从而保证基础的安全性。

Features

当然,它也具有一些特性:

  • 函数入参可以类比成Const T&,是只读的

  • 指针供给间接拜访和可变性

  • 通过包名来导入API

  • 默认情况下 class 是final的,abstract/base/final

  • 功用强大、通过定义检查的泛型以及接口完成 interface,相似 Rust 的trait

可是与Rust 相比,Carbon的榜首优先级是保证迁移性,也即是保证和C++之间的互操作性,可是Rust 的榜首优先级是安全性,从安全性上来说,Rust 要比 Carbon更安全。Rust 引进所有权机制来保证空悬指针和缓冲区溢出的问题。其实,C++供给的shared_ptr 和weak_ptr 组合起来也能完成这种所有权机制,即关于目标A,只能有其他一个目标具有 A 的 shared_ptr,可以有多个其他目标具有 A 的 weak_ptr。即永久不要用 shared_ptr 共享指针,共享要用 weak_ptr。但这种非强制性的要求并不能保证运用的安全性,由于你不能盼望所有的合作者都和你相同介意这些细节。Carbon在这条路径上如同并没有逾越Rust,只是比Cpp多了一些安全性的检查。

在ABI层面,Carbon 也仍是没有做出什么革新,不能保证ABI的一致性

规范库现在也不行完善,亟需社区来补齐才能。

Example

Talk is Cheap, Show me the Code

// 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;
}
// src/main.rs
#[cxx::bridge]
mod ffi {
    unsafe extern "C++" {
        include!("cxx-demo/include/blobstore.h");
        type BlobstoreClient;
        fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;
    }
}
fn main() {
    let client = ffi::new_blobstore_client();
}
// include/blobstore.h
#pragma once
#include <memory>
class BlobstoreClient {
public:
  BlobstoreClient();
};
std::unique_ptr<BlobstoreClient> new_blobstore_client();
// src/blobstore.cc
#include "cxx-demo/include/blobstore.h"
BlobstoreClient::BlobstoreClient() {}
std::unique_ptr<BlobstoreClient> new_blobstore_client() {
  return std::unique_ptr<BlobstoreClient>(new BlobstoreClient());
}
// 或许运用autocxx
autocxx::include_cpp! {
    #include "url/origin.h"
    generate!("url::Origin")
    safety!(unsafe_ffi)
}
fn main() {
    let o = ffi::url::Origin::CreateFromNormalizedTuple("https",
        "google.com", 443);
    let uri = o.Serialize();
    println!("URI is {}", uri.to_str().unwrap());
}

Conclusion

总而言之,这是一个实验性的言语,现在还不行完善,可是等它慢慢在社区的完善下走向成熟后,是有时机可以成为真实的C++ 接班人的。现在无论是东西链、IDE、一致包管理等都还需要进一步的开发,可是它的确提出了一些美好的愿景,在后C++时代为程序猿供给了更简略的高功用挑选。

In Google

在Google 内部,有两个叫Carbon的项目,一个是平台,另一个即为Carbon language,现在从infra内部来看,Carbon仍是归于啥都没有的PPT阶段,有着一些美好愿景,可是项目现在仍是处于十分初期的状况,亟需开源反哺。Chromium 从2020年开端就开端接触Rust团队,为cxx也产出了一些奉献,可是现在也没有看到源码中呈现Rust 的身影。Mozilla 的firefox的插件体系是由Rust编写的,现在线上的代码占比大概是10% 左右。这样看来,Carbon在Google内部的开展也是任重道远。

For Us?

假如 Carbon 真的可以生长起来,对广大开发者来说也是一种福音。期待 Carbon 生长成熟起来,不论是作为 C++ 的有力补充,或许是像 Kotlin 相同找到自己的着力点,总归期待它先在Google内部活下来,才有时机真实挑战 C++ 的霸主位置。

Reference

clang.llvm.org/docs/Introd…

en.cppreference.com/w/c/languag…

www.foonathan.net/2022/07/car…

github.com/google/auto…

cxx.rs/concepts.ht…

www.chromium.org/Home/chromi…github.com/carbon-lang…

carbon.compiler-explorer.com/