在 main() 内声明的函数是否具有外部链接或 none 链接?

Will a function declared inside main() have external linkage or none linkage?

见以下代码:

/* first file */

int i; /* definition */
int main () {
  void f_in_other_place (void);   /* declaration */
  i = 0
  return 0;
}
/* end of first file */


/* start of second file */

extern int i; /* declaration */
void f_in_other_place (void){   /* definition */
  i++;
}
/* end of second file */

我知道外部对象有 external 链接,内部对象有 none 链接(暂时忽略 extern)。现在,如果我谈论函数 f_in_other_place(),它是在 main 函数中声明的。那么它的标识符会被视为内部对象吗?如果是,则它应该具有 none 链接,但在程序中可见,此函数引用它在第二个文件中的定义,该文件表明它的标识符的行为类似于具有 external 链接的对象。所以我很困惑这里的标识符是否有 external 链接或 none 链接?

现在谈到 extern 关键字,我在某处读到函数声明隐式前缀 extern。因此,即使我没有明确提到此函数标识符的 extern ,默认情况下我的函数标识符是否会成为具有 external 链接并限定在 main() 范围内的对象?如果我走错了方向,请纠正我。

来自this linkage reference

external linkage. The identifier can be referred to from any other translation units in the entire program. All non-static functions, all extern variables (unless earlier declared static), and all file-scope non-static variables have this linkage.

[强调我的]

无论你在哪里声明函数,它总是有外部链接。

I know that external objects have external linkage and internal objects have none linkage

我认为术语“内部对象”是指在块作用域中声明的对象。

至于这个声明

int i; /* definition */

那就是声明了。你可以一个接一个地放置几个这样的声明,比如

int i; /* definition */
int i; /* definition */
int i; /* definition */

编译器在翻译单元末尾生成此变量的 so-called 暂定定义,将其初始化为零。

main then中的函数声明按照C标准(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. If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.

4 For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible,31) 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. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.

所以这个函数声明在main

void f_in_other_place (void);

相当于

extern void f_in_other_place (void);

由于文件范围内没有先前的函数声明,因此该函数具有外部链接。

例如,如果在 main 之前的文件范围内,将有一个带有关键字 static 的声明,如

static void f_in_other_place (void);

那么在 main 中声明的函数将具有内部链接。