在main内部声明的函数会具有外部链接还是没有外部链接?

问题描述

请参见以下代码

/* 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()内的对象吗?如果我走错了方向,请纠正我。

解决方法

我知道外部对象具有外部链接和内部链接 对象没有链接

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

此声明

int i; /* definition */

然后是一个声明。您可以像这样一个接一个地放置多个这样的声明

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

编译器在转换单元的末尾生成该变量的所谓临时定义,将其初始化为零。

然后根据C标准(6.2.2标识符的链接)在main中声明函数

5 如果函数标识符的声明没有 存储类说明符,它的链接被确定为完全一样 是使用存储类说明符extern声明的。。如果 对象标识符的声明具有文件范围并且没有 存储类说明符,它的链接是外部的。

4对于使用存储类说明符extern声明的标识符 在该标识符的先前声明为 可见的31)如果先前声明指定内部还是外部 链接,在以后的声明中标识符的链接是 与先前声明中指定的链接相同。 如果以前没有 声明可见,或者如果先前声明未指定 链接,则标识符具有外部链接。

所以这个函数在main中声明

void f_in_other_place (void);

等同于

extern void f_in_other_place (void);

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

例如,如果在main之前的文件范围中,将有一个像关键字static这样的声明

static void f_in_other_place (void);

然后main中声明的函数将具有内部链接。

,

来自this linkage reference

外部链接。可以从整个程序中的任何其他翻译单元引用该标识符。 所有非静态函数,所有外部变量(除非早先声明为静态)和所有文件范围的非静态变量都具有此链接

[重点突出]

声明函数的位置无关紧要,它将始终具有外部链接。