C函数声明链接

C function declaration linkage

我对 C17 标准中的一个主题有点困惑。

6.2.2第5点可阅读:

If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern. [...]

意味着它可以有内部或外部链接,这取决于该函数之前的其他声明(如果有的话)。

另一方面,在 6.7.6.3 示例 1(第 16 和 17 点)中,您可以阅读:

int f(void), *fip(), (*pfi)();

[...]

If the declaration occurs outside of any function, the identifiers have file scope and external linkage. [...]

所以,pfi 没问题(它不是一个函数,而是一个指针),但是 ffip 会发生什么?这不是自相矛盾吗?在 6.2.2 中,它“好像存在 extern storage-class 说明符”(这并不总是意味着它将具有外部链接),但在 6.7 中。 6.3外联好像是理所当然的

我错过了什么?

编辑: 更具体地说,如果我们在文件范围内有此代码:

// One random "previous declaration":
static int f(void);  // declares internal linkage
// Now, the important line, from the initial example:
int f(void);  // Internal linkage? External linkage?

6.2.2 声明第二个声明具有 内部链接

6.7.6.3 声明第二个声明具有 外部链接.

C 2018 6.7.6.3 16 中的示例代码可能是没有事先声明的独立代码,或者 C 2018 6.7.6.3 17 中文本的作者说“如果声明发生在任何函数,标识符都具有文件范围和外部链接”忽略了这样一个事实,即 f 可能由于先前与 static 的声明而具有内部链接,并且此新声明将保留该先前的链接。

如问题中所述,C 2018 6.2.2 5 说“如果函数标识符的声明没有存储-class 说明符,则其链接的确定与声明时完全相同storage-class 说明符 extern…”问题中未注明,6.2.2 4 说“对于范围内使用 storage-class 说明符 extern 声明的标识符其中该标识符的先前声明是可见的,如果先前声明指定了内部或外部链接,则后面声明中标识符的链接与先前声明中指定的链接相同……”当然我们知道 6.2。 2 3 告诉我们“如果对象或函数的文件范围标识符的声明包含 storage-class 说明符 static,则该标识符具有内部链接。”

因此,如果示例代码 int f(void), *fip(), (*pfi)(); 在先前文件范围 static int f(void); 可见的范围内,则示例代码中的 f 具有内部链接。

所以 C 2018 6.7.6.3 17 说 f 一定有外部链接是错误的,除非该示例旨在成为没有事先声明的独立代码。另外,6.7.6.3 17 是范例,“In ISO standards, examples are without exception non-normative.” 上面引用的其他文本是规范性文本,因此具有约束力,而6.7.6.3 17 中的范例则不是。