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

时间:2018-09-27 02:30:37

标签: c posix language-lawyer

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

  

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

但我什至不完全清楚应如何解释,当然,它不涵盖诸如sched.h之类的仅POSIX标头。

从上面的文字很明显:

  

可以以任何顺序包括标准头。在给定的范围内,每个元素都可以被多次包含,并且效果与仅被包含一次一样,...

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

1 个答案:

答案 0 :(得分:4)

要清楚了解下面引用的条款,请回想一下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节(编译环境)末尾:

  

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

链接: