C中是否需要函数的extern关键字?

时间:2011-03-10 04:39:23

标签: c extern

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

4 个答案:

答案 0 :(得分:12)

默认情况下,

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

extern Storage Class Specifier

  

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

     

...

     

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

答案 1 :(得分:12)

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

对我而言:

int func(int i);

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

extern int func(int i);

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

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

答案 2 :(得分:6)

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

实际上有三个考虑因素。

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

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

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

答案 3 :(得分:1)

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

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

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