Introduction
- JavaScript → TypeScript
- Java → Kotlin
- C++ → Carbon
Note that Carbon is not ready for use.
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/