我依稀记得一条规则:“C 标准库的头文件不得包含 C 标准库的任何其他头文件,除非特别允许”。但奇怪的是,我在C11中找不到这样的规则。我会在 7.1.2“标准标题”中期待它。
答案 0 :(得分:2)
据我所知,它没有明确声明为允许(或不允许)。但我相信以下段落暗示了这种可能性
<块引用>7.1.2 标准标题(强调我的)
4 如果使用,标头应包含在任何外部声明或定义之外,并且它应首先包含在对其声明的任何函数或对象的第一次引用之前 ,或它定义的任何类型或宏。
当我们在一致性部分交叉引用这个“应该”要求和它的含义时
<块引用>4.一致性
2 如果违反约束或运行时约束之外的“应该”或“不应”要求,则行为未定义。在本国际标准中,未定义的行为用“未定义的行为”一词或省略任何明确的行为定义来表示。这三者的侧重点没有区别;它们都描述了“未定义的行为”。
因此,如果调用 abs
函数而不包含 stdlib.h
,则行为将是未定义的。未定义行为就其本质而言包括事物“工作”的可能性。因此,如果另一个标准标头包含 stdlib.h
并且程序“有效”,则这符合上述合同。
答案 1 :(得分:2)
搜索从 Ansi-C (C90) 到最新草案的 C 标准,并进一步扫描历史参考资料,如 Unix V7 手册和 K&R 书籍,我找不到这条规则的参考。
标准头文件的内容、位置和实现是特定于实现的,一些类型和宏定义在多个头文件中,因此需要一个一致的方案来避免重新定义警告,并通过在常见 C 库实现中的条件包含来实现。< /p>
某些系统标头被明确指定为包括其他标头:
<块引用>7.25 类型泛型数学<tgmath.h>
标头 <tgmath.h>
包括标头 <math.h>
和 <complex.h>
并定义了几个类型泛型宏。
7.26 主题 <threads.h>
7.26.1 简介
标头 <threads.h>
包括标头 <time.h>
,定义宏,并声明支持多线程执行的类型、枚举常量和函数。
一些标准 POSIX 标头也被记录为包含其他系统标头。
除非程序员正在实现 C 库,否则该规则不会有任何区别:记录为定义标准类型、枚举常量、宏、函数或变量的系统头文件应在使用此标识符之前包含在内。系统标题可以以任何顺序包含,多个包含应该会导致任何问题。
答案 2 :(得分:2)
我依稀记得“没有C标准库的头文件 应包括 C 标准库的任何其他头文件,除非 特别允许”。
C 语言规范或 POSIX 标准中没有这样的规则。这两个,尤其是第一个,都避免指定诸如此类的实现细节。它们描述了用户可以依赖的积极结构和语义,但通常不限制实现以避免特定结构或细节。
在大多数情况下,标准也没有指定任何特定的头文件确实包含其他头文件,因此,出于风格和可移植性的考虑,编写代码就像没有标准一样是明智的标头包括任何其他。更一般地说,这导致了一个通用的样式指南,即您编写的每个源文件(包括标头)对于每个使用的标识符都应该适当地声明该标识符本身,或者 #include
记录来声明它的标头。
然而,正如@chqrlie 在 their answer 中指出的那样,标准明确指定某些标准库头文件包含特定的其他标准库头文件。
<块引用>但奇怪的是,我找不到这样的规则 写在 C11 中。我会在 7.1.2“标准 标题”。
这确实是人们在 C11 中会看到的地方。正如你所说,它表达的规则没有你描述的效果。
<块引用>Is there such a rule in C?
否,如上所述,这将与其他规定不一致。此外,在一些假定符合 C 的实现中,比@chqrlie 指出的do #include
其他标准库头文件更多的标准头文件。
Is there such a rule in POSIX?
否,如上所述,这将与其他规定不一致。此外,在一些假定符合 POSIX 的 C 实现中,比@chqrlie 指出的do #include
其他标准库头文件更多的标准头文件。
Is there such a rule in any other standard?
我不知道任何其他与 C 标准库相关的标准。代码约定是多种多样的,可以想象一个或多个关于编写程序和库头的规则是有的,但是标准库不在这些约定的范围之内。然而,显然没有人可以权威地谈论所有标准的范围。
提出 C11 的第 7.1.2/4 段也许也相关,其中部分内容是:
<块引用>标准标题可以以任何顺序包含;每个都可以包括在内 在给定的范围内不止一次,效果与被 只包含一次,除了 [关于 assert.h 的警告; ...]。但是,如果一个标识符被声明或定义在多个 一个标头,第二个和后续相关联的标头可能是 包含在对标识符的初始引用之后。
C 语言规范明确拒绝将标准库头文件实现为用 C 语言表示的普通源文件的任何要求,但请注意,在特定实现提供这种表示的程度上,这明确提出了以下可能性某些标识符可能由多个标头声明或定义。虽然不能保证一定会发生,也有其他可能发生的方式,但它与某些标头(包括其他标头)一致。