简体   繁体   English

标题是否存在而不是文件?

[英]Can header exist without being a file?

In C: The Complete Reference , Herbert Schildt says that 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. 但是,出于所有实际目的,标准c头文件包含在与其名称对应的文件中。

How can a header exist without being a file? 如何在不成为文件的情况下存在标题? What's the theme of this passage? 这篇文章的主题是什么? Because the .h file extension is used with a header. 因为.h文件扩展名与标题一起使用。

The C Standard does make a difference between header and source files referred to by #include preprocessing directives: C标准确实对#include预处理指令引用的头文件和源文件有所区别:

6.10.2 Source file inclusion 6.10.2源文件包含

Constraints 约束

1 A #include directive shall identify a header or source file that can be processed by the implementation. 1 #include指令应标识可由实现处理的头文件或源文件。

Semantics 语义

2 A preprocessing directive of the form 2表单的预处理指令

 # 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 3表单的预处理指令

 # 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 导致由“delimiters”之间的指定序列标识的源文件的全部内容替换该指令。以实现定义的方式搜索指定的源文件。如果不支持此搜索,或者搜索失败,该指令被重新处理,就像它读取一样

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

with the identical contained sequence (including > characters, if any) from the original directive. 使用原始指令中相同的包含序列(包括>字符,如果有的话)。

The compiler may implement a scheme where standard headers are not actually stored as files in the file system. 编译器可以实现一种方案,其中标准头实际上不存储为文件系统中的文件。 But the directive #include "filename.h" is specified as searching first for a file in a system specific way, and then searching standard headers as if the directive had been #include <filename.h> 但指令#include "filename.h"被指定为首先以系统特定的方式搜索文件,然后搜索标准头文件,就好像该指令已经#include <filename.h>

Note that the filename extensions .c and .h are purely a convention to distinguish files containing declarations and files containing actual code and data definitions. 请注意,文件扩展名.c.h纯粹是一种约定,用于区分包含声明的文件和包含实际代码和数据定义的文件。 Nothing in the Standard makes this convention a requirement, beyond the names used for the standard headers. 除了用于标准头文件的名称之外,标准中的任何内容都不需要此约定。 Some people use other conventions with different extensions or no extensions at all for specific needs, but the vast majority of C programmers would regard this as bad practice. 有些人使用具有不同扩展名的其他约定或根本没有扩展来满足特定需求,但绝大多数C程序员都认为这是不好的做法。

Shafik Yaghmour provided a quote from the C99 Rationale in an answer to a similar question that nails the committees intent on this matter: https://stackoverflow.com/a/27262904/4593267 Shafik Yaghmour提供了C99基本原理的引用,以回答一个类似的问题,指出委员会对这个问题的意图: https//stackoverflow.com/a/27262904/4593267

The C standard explicitly says that a header is a file, so I think not. C标准明确说明标题是一个文件,所以我认为不是。

6.10.2 Source file inclusion 6.10.2源文件包含

A #include directive shall identify a header or source file that can be processed by the implementation. #include指令应标识可由实现处理的头文件或源文件。

However, what counts as a file for the given system is implementation-defined. 但是,作为给定系统的文件的是实现定义的。 It could in theory be a hardware port, a pipe or some some other silliness. 它理论上可以是硬件端口,管道或其他一些愚蠢的东西。 Most of the major OS have the possibility to treat ports or pipes as files (for example in Windows, files and hardware ports are opened with the same function.) 大多数主要操作系统都可以将端口或管道视为文件(例如,在Windows中,文件和硬件端口使用相同的功能打开。)

An hypothetical C compiler is not required to need a file system. 假设的C编译器不需要文件系统。 It could process a #include directive otherwise: 它可以处理#include指令,否则:

  • it could query a database (IIRC some IBM compiler did that in the 1980s, the database contained a cache of the AST) 它可以查询数据库(IIRC,一些IBM编译器在20世纪80年代做过,数据库包含AST的缓存)

  • it could process standard includes otherwise, that is when it encounters #include <stdio.h> -in certain conditions- change its internal state (per what the standard requires) without accessing any header file . 它可以处理标准包括否则,即它遇到#include <stdio.h> - 在某些条件下 - 改变其内部状态(按照标准要求)而不访问任何头文件 In other words, standard headers could be "builtin". 换句话说,标准标题可以是“内置”的。

In practice, all the C compilers I know today are using a file system for headers. 实际上,我今天所知的所有C编译器都使用文件系统来标题。 But read about precompiled headers in GCC . 但请阅读GCC中的预编译头文件

BTW, the mention of "header file" in the C11 specification n1570 does not requires a file system (as in usual OSes). 顺便说一句,在C11规范n1570中提到“头文件”不需要文件系统(如在通常的操作系统中那样)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM