static与extern

最近在看链接与装载部分,对static与extern又有了新的体会。

声明与定义

声明:外部变量或函数的作用域从声明它的地方开始,到其所在的待编译文件末尾结束。

定义:定义全局变量或函数时,有两个功能,第一为它们分配存储空间(变量),第二声明它们。

1. 声明

  • 变量 : 必须加上extern
  • 函数 : 默认即为extern,可加可不加。

extern一般用于声明,为了说明全局变量或函数的定义在声明之后,或者定义和声明不在同一个文件中。 extern在目标文件的符号表里把符号(包括变量和函数)定义为 全局可访问符号 。因此extern声明的符号必须是全局可访问符号。

注:extern用于函数定义时,表示全局可见(即函数默认的状态,属于冗余,几乎不会这样用)。

总结:extern声明的符号说明了三点:

  1. 符号定义在它处
  2. 符号是全局可访问符号
  3. 符号作用域开始

2 .定义

定义:

  1. 全局变量定义 : 此变量可以被外部文件访问,变量值被放在.data或.bss段,因此所有访问共享一个变量值;
  2. 内部变量定义 : 此类变量不必放在符号表里,变量值运行时在栈段申请,因此也只能在函数被调用时访问;
  3. 函数定义 : 此函数可以被外部文件访问,C语言不允许函数嵌套定义,所以默认的函数定义必然是全局函数;

3. static定义

总体来说static会在目标文件的符号表里把符号(包括变量和函数)定义为 局部可访问符号 ,主要是改变符号的可访问域。 因此符号分为以下几种情况:

  1. static全局变量定义 : 此变量只能在本文件内访问,改变了全局变量默认的可访问域;
  2. static内部变量定义 : 此变量只能在本函数内访问,这有些特殊,变量值被改放在.data段或.bss段,因此此函数的多个调用共享一个变量值;
  3. 定义static函数 : 此函数只能在本文件内访问,改变了函数默认的可访问域;

第1种情况把 全局可访问变量 降为 局部可访问变量,第2种情况再把 局部可访问变量 降为 函数可访问变量, 逐步降低模块间的耦合度。

关键字static 有着不寻常的历史。起初,在C 中引入关键字static 是为了表示退出一个 块后仍然存在的局部变量。随后,static 在C 中有了第二种含义:用来表示不能被其它文件 访问的全局变量和函数。为了避免引入新的关键字,所以仍使用static 关键字来表示这第二 种含义。当然,C++里对static 赋予了第三个作用,这里先不讨论。

发表评论