header 可以不作为文件而存在吗?

Can header exist without being a file?

C: The Complete Reference 中,Herbert Schildt 说

Headers are usually files, but they are not necessarily files. It is permissible for a compiler to predefine the contents of a header internaly. However for all practical purposes, the standard c headers are contained in files that correspond to their names.

header 没有文件怎么可能存在? 这段经文的主题是什么? 因为 .h 文件扩展名与 header.

一起使用

C 标准确实在 header 和 #include 预处理指令引用的源文件之间有所区别:

6.10.2 Source file inclusion

Constraints

1 A #include directive shall identify a header or source file that can be processed by the implementation.

Semantics

2 A preprocessing directive of the form

# include <h-char-sequence> new-line

searches a sequence of implementation-defined places for a header identified uniquely by the specified sequence between the < and > delimiters, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined.

3 A preprocessing directive of the form

# include "q-char-sequence" new-line

causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the " delimiters. The named source file is searched for in an implementation-defined manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it read

# include <h-char-sequence> new-line

with the identical contained sequence (including > characters, if any) from the original directive.

编译器可能会实施一种方案,其中标准 headers 实际上并未作为文件存储在文件系统中。但是指令 #include "filename.h" 被指定为首先以系统特定的方式搜索文件,然后搜索标准的 headers,就好像指令是 #include <filename.h>

请注意,文件扩展名 .c.h 纯粹是一种约定,用于区分包含声明的文件和包含实际代码和数据定义的文件。除了用于标准 header 的名称之外,标准中没有任何内容使此约定成为一项要求。有些人使用其他具有不同扩展名或根本没有扩展名的约定来满足特定需求,但绝大多数 C 程序员会认为这是不好的做法。

Shafik Yaghmour 在回答类似问题时引用了 C99 基本原理,该问题明确了委员会对此事的意图:https://whosebug.com/a/27262904/4593267

C 标准明确表示头文件是一个文件,所以我认为不是。

6.10.2 Source file inclusion

A #include directive shall identify a header or source file that can be processed by the implementation.

但是,对于给定系统而言,什么算作文件是实现定义的。理论上它可以是硬件端口、管道或其他一些愚蠢的东西。大多数主要 OS 都有可能将端口或管道视为文件(例如在 Windows 中,文件和硬件端口以相同的功能打开。)

假设的 C 编译器不需要文件系统。否则它可以处理 #include 指令:

  • 它可以查询数据库(IIRC 一些 IBM 编译器在 1980 年代这样做,数据库包含 AST 的缓存)

  • 它可以处理标准包括否则,即当它遇到 #include <stdio.h> - 在某些条件下 - 更改其内部状态(根据标准要求)而不访问任何 header 文件。换句话说,标准 headers 可以是 "builtin".

实际上,我今天所知道的所有 C 编译器都在使用文件系统 headers。但是阅读 precompiled headers in GCC.

顺便说一句,C11 规范 n1570 中提到的 "header file" 不需要文件系统(与通常的操作系统一样)。