【问题标题】:C headers: compiler specific vs library specific?C 头文件:编译器特定与库特定?
【发布时间】:2014-08-02 23:13:03
【问题描述】:

C 编译器提供的标准 C *.h 头文件与标准 C 库提供的头文件之间是否有明确的区别?是否有一些列表或一些标准位置?

动机:int this answer 前段时间,关于最新的TinyC compiler中缺少unistd.h,作者认为unistd.h(与sys/unistd.h相反)不应该由编译器提供,而是由您的 C 库提供。

我无法理解这种反应(一方面,这不应该也适用于stdio.h 吗?)但我仍然想知道它。那是对的吗?这方面的权威参考在哪里?

查看其他编译器,我发现托管在 Windows 中的其他“自包含”POSIX C 编译器(例如 MinGW 附带的 GCC 工具链,有几个化身;或 Digital Mars 编译器)包含所有头文件。

在标准的 Linux 发行版(比如 Centos 5.10)中,我看到 gcc 包在 /usr/lib/gcc/i386-redhat-linux/4.1.1/include/glibc-headers 包中提供了一些头文件(例如,stdbool.hsyslimits.h)提供/usr/include/ 中的大部分标头(包括stdio.h/usr/include/unistd.h /usr/include/sys/unistd.h)。

因此,在这两种情况下,我都认为上述说法得到了支持。

【问题讨论】:

    标签: c gcc header-files standard-library


    【解决方案1】:

    不,没有明确的区别。

    就 C 标准而言 (here's a recent draft),编译器和库共同构成了实现,主要区别在于分别在标准的第 6 节和第 7 节中进行了描述.

    对于某些实现,编译器和运行时库由同一供应商/组织/人员提供,可以作为单个可安装包或作为两个单独的包提供。对于其他实现(包括 gcc),大部分标准库由底层操作系统提供,但编译器的安装包包含一些自己的头文件。

    另一个示例:当您在 Solaris 上从源代码安装 gcc 时,安装程​​序会运行一个脚本,该脚本会抓取一些现有头文件的副本(由 Sun 的 Oracle 的运行时库提供)并编辑它们,安装修改后的副本在一个单独的目录中。

    在 GNU/Linux 系统上,默认的 C 编译器通常是 gcc,而运行时库由 glibc 提供——这两个都是 GNU 包,但单独开发。 Windows 下的 MinGW 实现使用了 gcc 编译器和微软的运行时库(这会导致一些问题,因为他们不同意 long double 的表示)。

    编译器需要提供哪些标准头文件由编译器的作者选择。实现与特定编译器紧密相关的头文件(例如<stdint.h><limits.h><float.h>)通常由编译器提供;为操作系统服务提供接口的标头,例如 <stdio.h><stdlib.h>,通常由运行时库或操作系统提供。

    C 标准没有提供关于如何做出这种选择的直接指导。

    【讨论】:

    • 谢谢。您对链接的确认,unistd.hsys/unistd.h 的区别有什么看法?
    【解决方案2】:

    除了嵌入式(独立)C 实现之外,将 C 分离为编译器和库几乎没有意义。没有库的编译器和没有编译器的 C 库都没有多大意义。只有一个编译器和一个库才能构成一个完整的实现。

    从 C89 开始,标准库是 C 标准的一部分,标准中列出了所需的头文件列表。其他库集由 Posix、X/Open ... 请参阅此答案以获取列表:List of standard header files in C and C++

    有些头文件本质上更接近编译器本身,例如limits.h,指定数据类型的大小。一些头文件更接近操作系统,即 unistd.h。然而,在这两种情况下,都存在交叉点,如果操作系统的想法(例如 size_t)与编译器的实现不一致,那么什么都不会起作用。

    也有人认为unistd.h 应该由操作系统提供,而不是由 C 库提供 - 毕竟,如何调用内核函数的知识属于操作系统。

    总之,我认为这种区分编译器、C 库、操作系统的意义不大。

    【讨论】:

    • '没有库的编译器 [...] 没有多大意义。'有独立的实现,当然是有道理的。
    • @mafso 我知道这一点,但我认为问题作者已经考虑了托管实现。在独立式中,编译器基本上包含自己的库,这也是 IMO 分离论点被误导的一点。
    • OP 明确要求一个没有标准库的实现,它一个独立的。问题是,如果 <unistd.h> 必须是这种独立实现的一部分,并且 C11 §6.1 只需要标题 <float.h><iso646.h><limits.h><stdalign.h><stdarg.h><stdbool.h> , <stddef.h>, <stdint.h>, <stdnoreturn.h> 这样的实现。
    • @mafso:OP 对独立实现只字未提。对于许多托管实现,编译器和库(它们一起构成“实现”)碰巧是分开提供的。在大多数 Linux 系统上,C 实现由 gcc 和 glibc 组成。例如,在 Solaris 上,它可能由 gcc 和 Solaris 库组成。这意味着我不同意克里斯的回答;区别很重要,因为 C 实现可以由不同的组件组装而成。
    • "有一些标头(或标准用语中的“设施”)" -- C 标准不使用这个意义上的“设施”一词。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多