C中是否需要extern关键字function?

在我看来,即使我在另一个带有extern声明的文件中引用一个函数,gcc仍然可以编译该单元。 所以我想知道extern声明是否有必要在函数的任何地方? 我知道你需要extern变量。

函数默认具有extern存储类说明符(除非它们明确定义为static)

extern存储类说明符

如果声明描述函数或出现在函数外部并描述具有外部链接的对象, 则关键字extern是可选的 。 如果未指定存储类说明符,则假定该函数具有外部链接。

….

由于声明不兼容,在声明之前包含没有存储类说明符的存储类说明符static的同一函数的声明是错误的。 在原始声明中包含extern存储类说明符是有效的,并且该函数具有内部链接。

这没有必要,但我更喜欢在标题中加强这个函数在其他地方定义的想法。

对我来说,这个:

int func(int i); 

是以后需要的函数的前向声明,而这是:

 extern int func(int i); 

是一个函数的声明,将在这里使用,但在别处定义。

这两行在function上是相同的,但我使用extern关键字来记录差异,并与常规变量保持一致(差异重要,并且具有完全相同的含义)。

你不一定“ 需要extern变量。

当C被发明时,Unix连接器也被编写,并且他们以无知但聪明的方式推进了艺术。 一个贡献是将所有符号定义为小的“公共块”。 这允许声明的单一语法,没有必要的规范,哪个模块正在分配空间。 (实际上只有一个模块可以初始化对象,但不需要任何人。)

实际上有三个考虑因素。

  1. 原型的前向声明。 (可选,因为遗留C必须在没有它们的情况下进行编译。)

  2. 除一个文件外的所有文件中的非函数对象(变量)的外部声明。 (仅在非Unix系统上也需要使用可靠的链接器。希望这种情况很少见。)

  3. 对于函数,如果没有函数体来形成定义,则extern已经是假设。

据我记得标准, 默认情况下所有函数声明都被视为“extern” ,因此不需要明确指定它。 这不会使这个关键字无用,因为它也可以与变量一起使用(在这种情况下 – 它是解决链接问题的唯一解决方案)。 但是有了这些function – 是的, 它是可选的

更冗长的答案是它允许您使用在另一个源代码文件中编译的变量,但不为变量保留内存。 因此,要利用extern,您必须拥有源代码文件或库单元,其中包含顶层变量的内存空间(不在函数内)。 现在,您可以通过在其他源代码文件中定义同名的extern变量来引用该变量。

通常,应避免使用外部定义。 它们很容易导致无法管理的代码和难以定位的错误。 当然,有些例子表明其他解决方案不切实际,但很少见。 例如,stdin和stdout是映射到stdin.h中类型为FILE *的extern数组变量的宏; 此arrays的内存空间位于标准C库单元中。