外部变量声明和定义

时间:2012-05-04 16:17:43

标签: c variables external declaration definition

a)外部变量的定义与局部变量的定义相同,即int i=2;(仅在所有函数之外)。 但为什么extern int i=2;也像定义一样工作?是不是extern仅用于其他文件中的变量声明?

b)文件1

  #include<stdio.h>
  int i=3;
  int main()
  {
      printf("%d",i);
      fn();
  }

file2的

  int i;  //  although the declaration should be: extern int i; So, why is this working?
  void fn()
  {
      printf("%d",i);
  }

OUTPUT:两种情况下均为

2 个答案:

答案 0 :(得分:5)

由于历史原因,确定联系的规则以及声明提供定义的时间有点混乱。

对于您的特定示例,在文件范围

extern int i = 2;

int i = 2;

是等效的外部定义,如果您提供初始化程序,则extern是可选的。

但是,如果您不提供初始值设定项,则extern 可选:

int i;

是具有外部链接的暂定定义,它成为等同于

的外部定义
int i = 0;

如果翻译单元不包含具有显式初始化程序的其他定义。

这与

不同
extern int i;

这绝不是一个定义。如果已经有另一个相同标识符的声明可见,那么变量将从中获得它的链接;如果这是第一个声明,变量将具有外部链接。

这意味着在第二个示例中,file1和file2都提供了i的外部定义,这是未定义的行为,链接器可以自由选择它最喜欢的定义(它也可能尝试制作恶魔飞出你的鼻子)。 C有一个共同的扩展(见C99附件J.5.11和this question),这使得这个特殊情况得到了很好的定义。

答案 1 :(得分:1)

在C中,带有初始化的extern会导致分配变量。这就是声明将被视为一个定义声明。这与extern的更常见用法形成对比。

C标准说:

  

6.9.2外部对象定义

     

.....

     

如果对象的标识符声明具有文件范围和初始化程序,则   声明是标识符的外部定义。

至于问题的第二部分,文件范围内的声明int i具有外部链接。如果要为其提供内部链接,则需要声明它static int i。 C标准说:

  

6.2.2标识符的链接

     

...

     

如果对象的标识符声明具有文件范围而没有存储类说明符,则其链接是外部的。