C 和 POSIX 在哪里指定必须在文件范围内包含标准标头?



我只是切线处理了一个错误报告,其中软件在函数体内错误地执行了#include <sched.h>,我找不到权威文本说明这不是有效的用法。对于标准 C 标头,我能找到的最接近的是 7.1.2 ¶4:

如果使用,标头应包含在任何外部声明或定义之外,...

但我什至不完全清楚应该如何解释,当然它不包括像sched.h这样的仅限 POSIX 的标头。

从上面前面的文字中可以清楚地看出:

标准标头可以按任何顺序包含;每个标头都可以在给定范围内多次包含,与仅包含一次没有什么不同,...

如果允许包含在块范围内,则使用标准方法进行多重包含保护的实现无法满足该要求,但我希望看到更清晰的东西,以及 POSIX 中的内容。

为了明确下面引用的子句的措辞,请记住external declaration是在 C 语法中定义的(§6.9,外部定义(

translation-unit:
external-declaration
translation-unit external-declaration
external-declaration:
function-definition
declaration

因此,程序文本("翻译单元"(只是一系列外部定义。这与在"外部联系"中使用"外部"一词无关。如该节第4段所述:

...预处理后的程序文本单元是一个翻译单元,它由一系列外部声明组成。它们被描述为"外部",因为它们出现在任何函数之外(因此具有文件范围(。

因此,问题中引用的 §7.1.2¶4 中的限制适用于文件范围的任何声明或定义。(我不知道为什么标准说"外部声明或定义",因为外部定义集是外部声明的子集。但我看不出如何理解这句话来排除任何外部声明,即使是碰巧不是定义的声明。

在 Posix 中,系统接口第 2 章(一般信息(第 2.2 节(编译环境(末尾出现了基本相同的限制:

如果使用,应用程序应确保标头包含在任何外部声明或定义之外,并且应首先包含标头,然后首次引用它定义的任何类型或宏,或者它声明的任何函数或对象。但是,如果在多个标头中声明或定义了标识符,则第二个和后续关联标头可能包含在对该标识符的初始引用之后。在包含标头之前,应用程序不得定义任何名称与该标头定义的符号在词法上相同的宏。

链接:

  • 编译环境。引用的文本出现在该部分的末尾,因此您可以通过转到下一部分并向上滚动几个段落来更轻松地找到它。

最新更新