C 不再是一种编程语言

近日,Rust和Swift资深专家Aria Beingessner发布的一篇文章《C 不再是一种编程语言》在Hacker News上引起了热烈讨论 。
原文链接:
https://gankra.github.io/blah/c-isnt-a-language/
Hacker News评论区:
https://news.ycombinator.com/item?id=30704642
Aria和朋友Phantomderp在“对C ABI接口感到非常失望并试图修复上”达成了高度一致 。
但在失望的原因上,Aria与朋友各自持不同意见 。那具体产生了哪些分歧呢?为什么会提出C不再是一种编程语言的观点呢?笔者对原文进行了编译:
整理 | 于轩
出品 | 程序人生 (ID:coder _life)
Phantomderp试图从原生上改善使用C本身作为编程语言的条件,而Aria则希望改善使用C以外的任何语言条件 。
这时候大家就会产生疑问了,这个问题和C有什么关系?
Aria表示:如果C真的是一种编程语言,那就和它无关 。不幸的是,它并不是 。这不是说数十亿种实现方式和失败的层次结构,导致它的定义方式非常糟糕的事实,而是C被提升到一个具有威望和权力的角色,它的统治是绝对和永恒的 。C是编程的通用语言,我们都必须学C,因此C不再只是一种编程语言,它成了每一种通用编程语言都需要遵守的协议 。
这实际有点像是关于整个“C是一个不可捉摸的实现定义混乱”。但仅因为它让我们不得不使用这个协议,这就变成了一个更大的噩梦 。

C 不再是一种编程语言

文章插图
外部功能接口
下面一起来谈谈技术问题 。假如你已经完成了你的新语言BAppyscript的设计,对Bappy Paws/Hooves/Fins有一流的支持 。这是一种神奇的语言,将彻底改变cats、sheep、和sharks的编程方式 。
但现在需要让它真正做一些有用的事情 。比如接受用户的输入,或者输出,或者字面上的任何可观察之类的东西 。如果你想让该语言编写的程序与主流操作系统兼容,那就需要与操作系统的界面进行交互 。听说linux上的一切都“只是一个文件”,所以一起在Linux上打开一个文件吧!
OPEN(2)NAME open, openat, creat - open and possibly create a fileSYNOPSIS #include <fcntl.h> int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); int creat(const char *pathname, mode_t mode); int openat(int dirfd, const char *pathname, int flags); int openat(int dirfd, const char *pathname, int flags, mode_t mode); /* Documented separately, in openat2(2): */ int openat2(int dirfd, const char *pathname, const struct open_how *how, size_t size); Feature Test macro Requirements for glibc (see feature_test_macros(7)): openat: Since glibc 2.10: _POSIX_C_SOURCE >= 200809L Before glibc 2.10: _ATFILE_SOURCE这是Bappyscript,不是C,那Linux的Bappyscript接口在哪里?
你说Linux中没有Bappyscript接口是什么意思?好吧,当然是因为这是一种全新的语言,但你会添加一个,对吗?那这时你就会发现,你好像必须使用他们给的东西 。
你将需要某种接口,让语言能够调用外部的函数,就像外部函数接口FFI 。然后你发现Rust也有C FFI,Swift也有,甚至Python也有 。
C 不再是一种编程语言

文章插图
你会发现,每个人都必须学会C才能与主流的操作系统对话,然后当需要相互对话时,大家突然都用起了C 。所以…为什么不直接用C来相互对话呢?
现在C就变成了一种编程通用语言,不仅是一种编程语言,它还是一种协议了 。
C 不再是一种编程语言

文章插图
与C对话包括哪些内容?
很明显,基本上每种语言都必须学会与C进行对话,而且这种语言绝对是非常明确的 。
"对话 "C是什么意思?它意味着以C头文件的形式获得接口类型和功能的描述,并以某种方式:
  • 匹配这些类型的布局
  • 用链接器做一些事情,将函数的符号解析为指针
  • 用适当的ABI来调用这些函数(比如把args放在正确的寄存器中)
那么,这里就有几个问题:
  • 你实际上不能写一个C解析器
  • C实际上没有ABI,甚至没有定义的类型布局

C 不再是一种编程语言

文章插图
实际上无法解析一个C头文件


推荐阅读