代码之家  ›  专栏  ›  技术社区  ›  Rorsch

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

  •  8
  • Rorsch  · 技术社区  · 9 年前

    我很难理解除了C之外的编程语言的标准库是如何编写的。

    据我所知,C标准库可以在C和汇编程序的混合中实现,其中需要汇编程序,以便可以调用系统调用,从而 可以使用fopen、fscanf。

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

    我读过C和它的标准库可以用于实现其他语言库,但我不确定如何做到这一点。

    编辑1。 试着说得更具体些。
    (实现标准库的语言称为 新建(_L) .)

    如果有人能详细说明第二种方法是如何在目标代码级和实现级完成的(使用C运行时),因为有些事情我无法理解:

    1. C运行时是使用C语法还是new_lang语法调用的?如何从new_lang库中的某个位置调用ssize_twrite(int-fd,constvoid*buf,size_tcount)?
    2. 如果new_lang没有指针作为数据类型会发生什么, 常量void*buf 写入从newlang传递的?new_lang如何遵循 C运行时api 如果它没有C数据类型?
    3. 如果new_lang库中的某个函数调用C运行时,这是否意味着它必须遵守 阿比 ? 对于给定的平台,整数、char类型的数据大小必须在new_lang和C中匹配(以及由abi指定的其他内容,是堆栈或寄存器传递的参数等)?
      例如,如果new_lang需要为char保留更多字节,这不是有点过分限制了吗?

    我试图尽可能笼统,但我不知道如何解释这个问题,而不深入一点细节。

    1 回复  |  直到 9 年前
        1
  •  1
  •   Marco van de Voort    5 年前

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

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

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

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

    答复 编辑1 :

    1. Afaik与您使用的确切目标非常接近。系统编译器可以调用write(),但这可能是一个运行时(3)函数,它包装了syscall,而不是(2)直接的syscall。Afaik可以保证(3)函数实际上是函数而不是宏,但我不完全确定这一点。

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

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

    E、 g.自由Pascal具有cdecl;修饰符标记C可调用函数,然后编译器在该目标上生成与系统C编译器等效的调用代码。

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

    *nix上的许多语言都是这样的,因为快速创建新的初始端口更容易。但反过来,你需要维护一个混合语言系统。通常也会继承许多与构建相关的C特性,比如外部预处理器、标题作为文本包含并反复解释,以及基于make的构建系统。

    有关可能问题的列表,请参阅 How to design a C / C++ library to be usable in many client languages?

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