问题描述
请参见以下代码:
/* 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中声明的函数将具有内部链接。
,外部链接。可以从整个程序中的任何其他翻译单元引用该标识符。 所有非静态函数,所有外部变量(除非早先声明为静态)和所有文件范围的非静态变量都具有此链接。
[重点突出]
声明函数的位置无关紧要,它将始终具有外部链接。