编程语言的标准库是如何实现的?

Ror*_*sch 7 language-agnostic compiler-construction linker object-files

我在理解除 C 之外的编程语言的标准库是如何编写的有问题。

据我了解,C 标准库可以在 C 和汇编程序的混合中实现,其中需要汇编程序以便可以调用系统调用,因此可以使用 fopen、fscanf ...。

其他编程语言如何使用它们的标准库来完成这个功能(使用 i/o、文件、所有其他需要系统调用的东西)?它们是否都允许像 C 这样的汇编器内联,还是有其他方法?

我已经读过可以使用 C 及其标准库来实现其他语言库,但我不确定这是如何完成的。

编辑1. 试图更具体。
(实现标准库的语言称为new_lang。)

如果有人可以详细说明如何在对象代码级别和实现级别完成第二种方法(使用 C 运行时),因为我无法理解的是:

  1. C 运行时是使用 C 语法还是 new_lang 语法调用的?我们如何从 new_lang 库中的某个地方调用 ssize_t write(int fd, const void *buf, size_t count) ?
  2. 如果 new_lang 没有指针作为数据类型会发生什么,第二个参数const void *buf to write是如何从 new_lang 传递的?如果 new_lang没有 C 数据类型,它如何跟随C 运行时 api
  3. 如果 new_lang 库中的某个函数调用 C 运行时,是否意味着它必须遵守其abi?整数类型的数据大小,char,必须在 new_lang 和 C 中匹配给定平台(以及由 abi 指定的其他内容,参数是通过堆栈还是寄存器等传递)?
    这不是有点过度限制,例如,如果 new_lang 需要为 char 保留更多字节怎么办?

我试图尽可能笼统,但我不知道如何在不详细说明的情况下解释这个问题。

Mar*_*ort 1

这取决于语言,甚至可以是多项选择。请注意,用 C 实现的标准库/运行时通常使用编译器特定的扩展和属性,因此不是用标准未扩展 C 编写的。

对于像 Pascal 这样的语言,多种方法是可能的并且确实存在。Pascal 是一种与 C 处于同一级别的语言(和/或 C++,因为大多数幸存的语言也是面向对象的),例如FreePascal在 Pascal 和汇编程序中拥有其运行时库,并且可以在 Linux 上运行而无需链接到任何 C 编译代码。

选择 C ​​的原因通常更多的是管理(工具和程序员的可用性)而不是技术

同时Gnu Pascal基本上是一个 gcc mod,并且构建在 libgcc、glibc 等之上。

回答编辑1

  1. Afaik,这对于您正在使用的确切目标来说是非常内部的。有一些 write() 可以从系统编译器调用,但这可能是包装系统调用的运行时 (3) 函数,而不是直接 (2) 系统调用。据我所知,可以保证 (3) 函数确实是函数而不是宏,但我对此并不完全确定。

在 BSD 上,系统调用与函数调用相当相同,但在 Linux/i386 上则不然。语法并不重要,生成的代码必须是等效的(不相同,但接近)。语法本身并不重要,重要的是C编译器如何解释语法。通常唯一保证工作的东西(就经典 POSIX 哲学而言)是系统C 编译器,它是唯一保证能够解释系统头文件的编译器,因为它们通常包含非标准扩展或修饰符。其他任何事情都必须确保它匹配,可能是基于每个目标。因此,大多数语言都构建在 C 运行时之上,并且通常有自己的运行时的 C 部分。

  1. 您必须以某种方式使它们在每个目标的基础上与每个目标的 C 编译器相匹配,要么通过自动适应(您的整个系统基于 C,并且 C 编译器和类型等效性在某种程度上自动传播),要么通过痛苦的逐个目标目标是制作一些等效项,或者将每个函数包装在 C 或汇编代码中。有时每个目标多次(例如 MS VC 和 mingw,尽管最近这些比 10-15 年前更兼容,当时 gcc 不兼容 COM)

例如 Free Pascal 有一个 cdecl;修饰符来标记 C 可调用函数,然后编译器会生成与该目标上的系统 C 编译器等效的调用代码。

这听起来很糟糕,但通常只有几个变体。但这仍然不容易,例如,Linux/FreeBSD 一侧(sysv)、Windows(win64 自己的约定)和 OS X(aix 约定)之间的 x86_64 API 略有不同。人们可以通过尽可能多地用 C 实现整个系统来避免这种情况,但这样你就永远受困于它(以及混合语言系统)。此外,这样 Cisms 和 Unixisms 就会渗透到你的新语言中,因为它更容易。

*nix 上的许多语言都采用这种方式,因为更容易快速地初始移植到新的东西。但反过来你可以维护一个混合语言系统。通常还继承许多与构建相关的 C 特征,例如外部预处理器、作为文本包含的标头并一遍又一遍地重新解释,以及基于 make 的构建系统。

有关可能问题的列表,请参阅如何设计可在多种客户端语言中使用的 C / C++ 库?

  1. 是的,但仅限于它的二进制部分,因为 C 编译器当然不能执行严格形式的类型检查。但是大小、字段偏移量(打包)、调用顺序、寄存器使用以及小结构是否在寄存器中传递之类的内容必须匹配。