写点什么

没有永远的王者…Zig 替代 C,将成定局!

  • 2023-08-30
    福建
  • 本文字数:3684 字

    阅读完需:约 12 分钟

没有永远的王者…Zig替代C,将成定局!

新语言的出现,真的能威胁到老牌语言吗?或许,真的没有永远的王者。就像最近春风得意的 Mojo,LLVM 之父 Chris Lattner 称其不会威胁到 Python,但会让 C++等语言感到恐惧。


新语言层出不穷之时,旧语言的中年危机就会愈发凸显。但像 C++、C 好似一直稳坐钓鱼台,“一直被唱衰,但从未被打倒”。


但总会有新的挑战者,比如 Zig、Go 跃跃欲试,试图取代这个编程老祖。而且许多新语言的使用者也会幡然相信:C,或许真的需要进化了!


本篇文章具体解释了目前在所有 C 的替代品中,Zig 为什么是最好的,以及 Zig 本身已经有了可行的替代 C 的计划,诸君不妨一探究竟。

1、C 那么牛,为什么会有许多替代品?


诚然,C 傲视群雄的资本还是有目共睹的,毕竟这门编程老祖之所以如此霸气,是因为它是每个现代软件系统组件的创造者。开发人员用 C 语言制作 web 服务器、数据库、操作系统、框架、编程语言、云组件和许多软件组件。尽管许多编程语言都说它们可以“取代”C 语言,但这是不可能的,因为整个计算机历史都是用 C 语言创造的。


但资格老的语言总是不太能跟上“现代开发”的脚步。C++语言通过实现面向对象的概念、生产语言特性和通过保持 C 语言的性能优先设计的标准库 API,为现代开发人员改进了 C 语言语法。也有一些 C 替代方案可以解决每个 C 开发人员面临的问题。Zig、D、Go 和 Odin 是流行的 C 语言替代品。


Zig 展示了一个充满希望的未来,有一个内置的包管理器、一个构建系统、类似 C 但更好的语言语法、一个功能齐全的标准库和一个不断增长的社区。像 Uber 这样的大企业也开始使用 Zig 工具链进行交叉编译。此外,一些软件公司开始使用基于 Zig 的代码存储库开展业务。我将用这个故事解释 Zig 如何成为 C 语言的最佳选择。

2、为什么 Zig 只能替代 C,而不是 C++


系统编程通常指的是开发更接近计算机硬件或操作系统层的东西。系统编程通常实现可以运行其他软件系统的软件模块。编写操作系统、应用程序框架和嵌入式系统是系统编程的好例子。系统程序员主要有两种语言类型选择:


  • C 及其替代方案:使用小型的高性能语言,如传统的 C、Go、Zig 或 Nim。

  • C++及其替代方案:使用有点复杂、高性能的语言,如传统的 C++、Rust、Carbon 或 Cppfront。


Zig 属于第一种语言。它是一种小型的、类似 C 语言的高性能语言,没有专用的运行时(没有内置的垃圾收集器)。Zig 试图通过解决 C 开发人员面临的问题来成为“更好的 C 语言”,而 Rust 试图成为“更好的 C++”语言。

3、Zig 如何成为最好的 C 替代品?


C 语言现在有一个标准规范,也有了几个实现。例如,你可以在 GNU/Linux 系统上使用 GNU C 编译器,在 macOS 上使用 Apple Clang,在 Windows 上使用 MSVC。C 也有多个标准库实现,如 libc、Microsoft C 运行库、BSD libc、musl、Bionic 等。


一个编译器实现和一个基本的标准库是不足以高效地构建软件系统的——C 程序员需要使用构建系统、包管理器、测试运行器等。对于这些工具,他们要么必须使用现有的第三方工具,要么编写自己的工具(如 BuildZri 构建系统)。


Zig 提供了一个内置的构建系统、包管理器和测试运行器。Zig 通过为 C 开发人员经常面临的问题提供解决方案来与 C 竞争。例如,Zig 的官方编译器支持交叉编译,并且内置的测试运行器可以执行放在源代码本身内部的测试用例。Zig 的语言设计倾向于通过维护类似 C 的硬件友好设计来提供更高效的开发人员友好特性。Zig 是硬件友好的,但它是最小的、安全的、语法上类似 Rust 的和现代的。因此,开发人员可以比 C 更高效地使用它。


看看下面这些简单的 Zig 代码片段,来理解 Zig 未来的、硬件友好的语言概念:


const std = @import("std");
pub fn main() void { var nums = [_]u8{1, 2, 4, 5, 120}; var x: usize = 3; var nums_seg = nums[1..x];
std.debug.print("{any}\n", .{nums_seg}); // { 2, 4 } std.debug.print("{}\n", .{@TypeOf(nums_seg)}); // []u8 (slice)}
复制代码


Zig 不像 C 语言那样使用预处理器或宏系统来处理导入——它使用类似 nodejs 的模块导入语法和内置的 @import 函数。这里,我们使用 u8 基本类型创建了一个无符号字节大小的整数数组。然后,我们使用 Zig 切片概念从数组创建一个切片。正如你所看到的,Zig 提供了一个类似于 C 的硬件友好的原子类型系统,但是它使用更好的标准化、自解释的命名来改进它们,而不像 c 中那样使用 char、short、long 等。


C 通常要求程序员自己保护他们的程序,但是 Zig 实现了严格的内存安全特性。尝试将 256 添加到上面的字节数组。如果你用 C 语言做这个实验,程序会静默地存储一个不正确的值。在 Zig 中,你会得到一个编译错误,因为 255 是无符号字节类型可以表示的最大值:



(Zig 编译器显示的整数溢出检查)


Zig 的内置测试运行器和单元测试 API 允许你在源文件中编写测试:


const std = @import("std");
fn add(a: i8, b: i8) i8 { return a + b;}
test "add returns the summation" { try std.testing.expectEqual(add(10, 5), 15);}
复制代码


我从未在其他流行语言中见过像 Zig 这样高效的 C-互操作。大多数语言使用 FFI(外部函数接口)来实现 C-互操作,但是 Zig 允许你调用 C,甚至不需要在 Zig 范围内定义 C 函数。当你导入 C 头文件时,它会自动创建结构类型:


const std = @import("std");
fn add(a: i8, b: i8) i8 { return a + b;}
test "add returns the summation" { try std.testing.expectEqual(add(10, 5), 15);}
复制代码


如上面的代码片段所示,Zig 允许你像调用本地 Zig 函数一样调用 C 函数,但是使用自定义前缀(经常使用 C)。


Zig 没有提供一个内置的字符串类型,但是它允许你通过一个类似 C 语言的、低级的、基于字符数组的字符串处理概念和有用的快捷方式来处理字符串:


std.debug.print("{s}\n", .{"Zig" ++ "Lang"});   // ZigLang (concatenation)std.debug.print("{s}\n", .{"Zig" ** 5});   // ZigZigZigZigZig (repetition)std.debug.print("{}\n", .{@TypeOf("string")});   // *const [6:0]u8 (a pointer to an unsigned byte array)
复制代码


Zig 语言更接近硬件层,但它实现了各种快捷方式和现代语言概念(即,切片、内置函数、循环简写等),为系统编程提供了一种高效的语言。其功能齐全的模块化标准库帮助 Zig 超越了系统编程。它为你提供了你在通用编程语言中寻求的控制结构、数据结构和基本算法,这也非常适合系统编程。


Zig 工具链的特性,如交叉编译和构建系统 API,激励程序员在现代系统编程中选择 Zig 而不是 C!对于现有的 C 代码库,Zig 工具链提供了一个可替换的 C/ C++编译器和 C 互操作,因此程序员可以将传统的 C 代码库增量地迁移到现代的 Zig。

4、Zig 语言和工具链的突出特点


我们讨论了一些突出的 Zig 语言/工具链事实,并了解了它如何以成为“更好的 C”语言为目标。许多 Zig 特性促使我们选择它作为系统编程的 C 替代方案。


看看以下突出显示的功能总结:


  • Zig 提供的不仅仅是一种简单的语言——它是一个功能齐全的工具链,用于开发、测试、构建和发布系统编程项目

  • 它的开发人员友好的 CLI 可以立即支撑可执行和共享库项目。

  • Zig 允许您调用 C,但它不依赖于 C——libc 是 Zig 二进制文件的可选组件。

  • Zig 没有专用的运行时,因为它没有自动垃圾收集器——所以它可以生成快速、轻量级的二进制文件。

  • 尽管 Zig 通常是一种中级语言,但它提供了现代的通用特性,如异步编程语法、泛型和类型强制转换(自动和手动)。

  • Zig 工具链可以通过交叉编译来编译 C/ C++,因此您可以在使用 Zig 语言之前使用它的 C/ C++编译器来构建现有的 C 代码库。

  • 一个编写良好的、模块化的、功能齐全的标准库,包括跨平台的操作系统级 api,如 Python。

  • 它提供了生产力优先的语言特性,而不会损害硬件友好的系统编程环境,例如,for-in 循环、多个切换用例(切换范围)、内联 for、切换语句等。

  • 它附带了基于流行的 C 编程模式的基于枚举的错误处理方法,没有复杂的、容易出错的异常概念。

  • 它允许您通过分配器概念和 defer 关键字进行手动内存管理。


所有没有专用运行时的语言,如 C、C++、Rust 和 Zig,都会从用特定语言编写的每个源代码生成原始汇编,因此系统编程语言的性能取决于二进制文件中汇编代码的质量。系统编程语言的编译器要么使用 LLVM 优化,要么使用它们自己的成熟优化,因此很难说哪种语言更快——系统编程性能通常取决于程序员编写的算法。

5、具有长期计划的替代方案


到目前为止,我们已经讨论了如何通过语言和工具链特性使 Zig 成为更好的 C 替代方案。性能如何?它的性能比 C 好吗?


然而,Zig 官方文档声称,由于基于 llvm 的优化和增强的未定义行为,Zig 比 C 运行得更快。此外,Zig 还计划通过移除作为依赖项的 LLVM 来进一步改进 Zig。Zig 软件基金会(ZSF)积极维护该项目,并接受来自社区的新设计建议。


Zig 充满希望的未来使它成为最好的 C 语言替代品,甚至促使 C 程序员将他们现有的代码库迁移到现代的 Zig。

6、结语


在这个故事中,我们讨论了 Zig 如何通过提供小型的、开发人员友好的、硬件友好的、高效的、高性能的和安全的语言设计,成为“更好的 C”语言。改进的语言设计和工具链帮助 Zig 在使用 C 的用例中表现良好,例如构建操作系统、库、云计算模块和框架。此外,其未来的语言功能甚至可以与流行的 Go 语言竞争!


尽管 Zig 或任何其他未来的系统编程语言永远不会“取代”C/C++,但随着现代化进程的加速,Zig 已经成为有史以来最好的 C 语言替代品之一。

发布于: 刚刚阅读数: 3
用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
没有永远的王者…Zig替代C,将成定局!_C语言_互联网工科生_InfoQ写作社区