简体   繁体   English

C 函数声明链接

[英]C function declaration linkage

I'm a bit confused with a topic in the C17 standard .我对C17 标准中的一个主题有点困惑。

In 6.2.2, point 5 you can read:在 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.如果函数标识符的声明没有存储类说明符,则它的链接将完全确定,就好像它是使用存储类说明符 extern 声明的一样。 [...] [...]

Meaning that it could have either internal or external linkage, depending on other declarations (if any) of that function before that one.这意味着它可以具有内部或外部链接,具体取决于该函数之前的其他声明(如果有)。

On the other hand, in 6.7.6.3, example 1 (points 16 and 17), you can read:另一方面,在 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.如果声明出现在任何函数之外,则标识符具有文件范围和外部链接。 [...] [...]

So, it's ok with pfi (it's not a function, but a pointer), but what happens then to f and fip ?所以, pfi没问题(它不是一个函数,而是一个指针),但是ffip会发生什么? Isn't that a contradiction?这不是矛盾吗? In 6.2.2, it's "as if the extern storage-class specifier was present" (which doesn't always mean it will have external linkage), but in 6.7.6.3 it seems the external linkage is given for granted.在 6.2.2 中,它“好像存在外部存储类说明符”(这并不总是意味着它将具有外部链接),但在 6.7.6.3 中,外部链接似乎是理所当然的。

What am I missing?我错过了什么?

Edit: to be more specific, if we have this code in file scope:编辑:更具体地说,如果我们在文件范围内有此代码:

// 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 states that the second declaration has internal linkage . 6.2.2 声明第二个声明具有内部链接

6.7.6.3 states that the second declaration has external linkage . 6.7.6.3 声明第二个声明具有外部链接

Either the example code in C 2018 6.7.6.3 16 was intended to be stand-alone code with no prior declarations or the authors of the text in C 2018 6.7.6.3 17 that says “If the declaration occurs outside of any function, the identifiers have file scope and external linkage” overlooked the fact that f could have internal linkage due to a prior declaration with static and that this new declaration would retain that prior linkage. C 2018 6.7.6.3 16 中的示例代码旨在成为没有事先声明的独立代码,或者 C 2018 6.7.6.3 17 中文本的作者表示“如果声明发生在任何函数之外,则标识符具有文件范围和外部链接”忽略了这样一个事实,即f可能由于先前的static声明而具有内部链接,并且此新声明将保留该先前的链接。

As noted in the question, C 2018 6.2.2 5 says “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 …” Not noted in the question, 6.2.2 4 says “For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration…” And of course we know 6.2.2 3 tells us “If the declaration of a file scope identifier for an object or a function contains the storage-class specifier static , the identifier has internal linkage.”如问题中所述,C 2018 6.2.2 5 说“如果函数的标识符声明没有存储类说明符,则其链接的确定与使用存储类说明符extern声明时完全相同......”不是在问题中指出,6.2.2 4 说“对于使用存储类说明符extern在该标识符的先前声明可见的范围内声明的标识符,如果先前声明指定内部或外部链接,则后面声明的标识符与前面声明中指定的链接相同……”当然我们知道 6.2.2 3 告诉我们“如果对象或函数的文件范围标识符的声明包含存储类说明符static ,标识符具有内部链接。”

Thus, if the example code int f(void), *fip(), (*pfi)();因此,如果示例代码int f(void), *fip(), (*pfi)(); in a scope in which a prior file-scope static int f(void);在先前的文件范围static int f(void); is visible, then the f in the example code has internal linkage.可见,则示例代码中的f具有内部链接。

So C 2018 6.7.6.3 17 is wrong to say f necessarily has external linkage unless the example is intended to be stand-alone code with no prior declarations.因此,C 2018 6.7.6.3 17 说f必然具有外部链接是错误的,除非该示例旨在成为没有事先声明的独立代码。 Further, 6.7.6.3 17 is example text, and “In ISO standards, examples are without exception non-normative.”此外,6.7.6.3 17 是示例文本,并且“在 ISO 标准中,示例无一例外是非规范性的。” The other text quoted above is normative text, so it is binding and the example text in 6.7.6.3 17 is not.上面引用的其他文本是规范文本,因此具有约束力,而 6.7.6.3 17 中的示例文本则没有。

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

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