【编译】全局变量使用问题

一、C全局变量编译

模块1:UITest.h、UITest.cpp       模块2:MyTest.cpp     模块3:cTest.cpp【main】

//UITest.h
int a = 5;
int add();
//UITest.cpp        -模块1
#include "UITest.h"  
int add()
{
     a +=a;
     return a;
}
//MyTest.cpp        -模块2
//#include "UITest.h"    否则编译出错

 extern int a;//如果改成 static int a;表示是当前模块的一个变量,与外部无关,这样也可以和全局变量重名。
int sub()
{
    return a/2;
}
//cTest.cpp         -主模块
extern int a;       //引用外部全局变量
extern int add();   //引用外部函数
extern int sub();
int main(int argc, char* argv[])
{
 cout<
【点评】主模块中,extern说明引用的是外部变量和函数,这时编译器会扫描所有的符号表,来填充本模块的地址。会在外部的模块中查找变量a和函数add()、sub()。

在模块2中,如果#include "UITest.h",则编译出错提示:a已经在UITest.obj中定义,原因是编译时产生几个表:未解决符号表,导出符号表和地址重定向表等。include之后,全局变量放在模块的导出符号表,模块1和模块2有相同的a,所以报错。
         然而,extern会把符号放在obj文件中的未解决符号表中,而不是在导出符号表中。

         导出符号表具有唯一性,而未解决符号表依赖于导出符号表。

二、另外一种全局变量引用的方法        

//module1.h
extern int a;
//module1.c
#include "module1.h"
int a = 5;
//module2.c
#include "module1.h"
//module3.c
#include "module1.h"
        全局变量,放在cpp文件中定义,这样3个模块都共用了全局变量a,因为#include的只是extern int a。编译器扫描到头文件,会将其加入到未解决符号表。

参考:1、C++编译链接那些事

2、用extern定义全局变量

3、C语言中声明和定义的区别

4、C语言头文件规则

你可能感兴趣的:(编译分析)