符号的作用域

在C/C++里,我们可以将变量名和函数名统称为符号。符号的作用域,是指该符号的有效作用范围。

对于变量来说,常见的有三种:局部变量、静态变量和全局变量。而函数则有静态函数和全局函数之分。

在学习编程语言时,我们通常从源文件的角度来理解,比如静态变量或者静态函数只能被它所在文件的其它函数访问或者调用,无法在其它文件里引用。但是#include的存在使得问题复杂了,比如在头文件里定义的静态函数当然可以在包含它的文件内引用。

由于动态共享库的存在,全局的概念也不像我们通常想像的那么简单。实际上,一个定义在动态共享库里的全局变量,可以被执行程序或者其它动态共享库引用,甚至一个定义在执行程序里面的全局变量,也可以被它链接的动态共享库引用。所以,全局的意思,是指整个进程的范围,而不仅仅是可执行程序了。

在这些由语言提供的作用域不够用的时候,我们还可以考虑使用GCC提供的可见度(visibility)这个作用域,通过把可见度设置为隐藏,全局变量的作用域被限制在其所在的执行程序或者动态共享库内。设置方法有很多种,比如使用pragma或者attribute在源代码里指定、使用命令行选项,以及在链接脚本里面指定。具体使用方法参见gcc手册。

其实,从程序逻辑的角度来说,我们根本就不需要这些区分。引入这么多概念,都是为了解决开发中的实际问题。尤其是在引入了动态共享库和动态链接之后,全局符号导致问题更加复杂,因此,如果没有特殊需要,尽可能缩小符号的作用域。