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

Nos*_*iii 12 c external function extern 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 */
Run Code Online (Sandbox Code Playgroud)

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

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

Vla*_*cow 8

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

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

至于这个声明

int i; /* definition */
Run Code Online (Sandbox Code Playgroud)

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

int i; /* definition */
int i; /* definition */
int i; /* definition */
Run Code Online (Sandbox Code Playgroud)

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

至于 main 中的函数声明,则根据 C 标准(6.2.2 标识符的链接)

5如果函数的标识符声明没有存储类说明符,则其链接的确定与使用存储类说明符 extern 声明的完全相同。如果对象的标识符声明具有文件范围且没有存储类说明符,则其链接是外部的。

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

所以这个函数在 main 中声明

void f_in_other_place (void);
Run Code Online (Sandbox Code Playgroud)

相当于

extern void f_in_other_place (void);
Run Code Online (Sandbox Code Playgroud)

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

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

static void f_in_other_place (void);
Run Code Online (Sandbox Code Playgroud)

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