医馆笑传2太监胡砺金:C/C++中extern的作用

来源:百度文库 编辑:偶看新闻 时间:2024/04/29 02:01:47
extern   "c"     表示函数使用C的连接方式,也就是说能被C语言写的程序调用(C和C++的连接方式是不一样的)。  
  联想   extern   "C++"大概也知道了吧  
   
  在C++程序中调用被C编译器编译后的函数,为什么要加extern“C”声明?  
  因为    语言和   C++   语言的编译规则不一样,所以要告诉系统哪些函数是用    方式编译,哪些函数需要用   C++   方式编译。  
  如果你不加   extern   "C"   ,在编译时,系统会提示找不到此函数。  
   
  extern   "C"表示编译生成的内部符号名使用C约定  
  例如:  
  int   Fun(int   i,int   j)  
  C:_Fun  
  C++:_Fun_int_int  
  具体生成什么可能与编译器有关  
  由于C++支持重载,而重载是在编译期确定的,所以C++必须在内部符号名上区分各重载函数,所以就将参数类型加在函数名后。  
   
   
  extern关键字告诉编译器,“这个变量可能定义在这个模块或其它模块中”,一个extern声明并没有生成数据,它仅表明这个数据是共享的。这个变量必须是在别处定义过的,而且它只能定义一次  
  例子如下:  
  extern   "C"   declaration;  
  其中"C"是可选的,包括“C”表明这个条目是根据C语言的约定 来声明的。这个特征使得C语言的模块,不必象C++代码需要进行对名字改写和编译而可以直接访问这些条目。  
   
   
  以下是C++Primer上的一段话  
  如果成员希望呼叫以另一种语言写成的程式,编译器必须控制函式呼叫时的不同需求。例如,c++和其他语言对于汉式命名方式或引数传递次序可能与所不同。  
   
   
  这个问题要涉及一个基本的知识就是你要知道编译器的处理过程是什么的,知道的结果就是了解source   file和translation   unit的联系和区别。  
  说简单一点translation   unit就是编译器处理过的source   file。处理包括词汇分析,预处理等等,对于你的问题,重要是理解#include的处理意思,是包含#include文件内容使之成为本身的一部分。  
  说到你这个问题,  
  简单说就是“外部连接”的实体(包括变量,函数等)可以在定义实体的translation   unit以外的部分(程序空间)被引用,但是“内部连接”的实体只能在定义实体的translation   unit中使用。  
   
   
  去看看汇编中对于obj文件中的名字连接属性的讲解吧。  
  简单地说就是:一个transunit会编译出一个obj文件,不同的obj文件是分开编译的,在连接时,具有internal   linkage的名字不可能被其他的obj文件所使用,只有具有external   linkage的名字才可以被别的obj文件所使用。  
  举例来说就是,一个函数,如果不具有external   linkage的话,那它只可以在实现它的那个transunit中被调用,在其他的transunit中被调用会引发linker的一个连接错误。  
   
   
  extern   "C"用在C++里表示,被其修饰的函数,类,结构在编译时按照C的编译规则进行,没有mangling  
  在C++中,由于某种原因,比如重载:不同函数体的函数可能有着相同的名字,当然这是相对于程序员来说,实际上,为了区分这些有着相同名字的重载函数,C++编译器偷偷的在背后给这些函数取了特殊的名字以区分它们,这就被称为C++的mangling。  
  同样的,类中的变量有可能与类外的变量同名,当然我们编程时可以用"."来区分,而编译器在编译时,则是通过mangling为类中的变量取了一个独一无二的名字,这个名字显然与程序员所取的名字不同。  
  加了extern   "C"后就不会mangling,函数(或类之成员变量)是什么名字,在编译器编译过程中仍然是这个名字,生成的目标文件.obj里这个函数还是这个名字。  
   
   
  extern   int    表示   a是在其它文件中定义的一个变量,需要在这里引用。  
  a已在别的文件中,所以不需要再分配空间了  
   
   
  extern   int    定义的a变量表示该变量在使用前已经定义了,一般有两种情况,一是该变量是在其他的文件中定义的全局变量,简称外部变量。二种情况表示变量在本文件中定义的全局变量,但是在使用之后(因为作用域)定义的。  
   
  extern   int    是对变量的声明,而不是定义,该变量是其他文件中定义的,或是本文件中在该声明之后定义的全局变量。  
   
   
  extern   int   a;//这是变量声明,是告诉编译器到该文件外部去找这个文件的定义  
                              //声明是不分配内存的  
  int   a;//这是变量定义,变量定义是分配空间的  
  定义只能有一处,但声明可有多处,这些声明所指,都是定义时分配的内存空间  
   
   
  static和extern都被称为"global"变量(或者函数)。  
  但是他们的生存周期和可见性是不同。static是文件级,  
  只有程序文件之间显式的包含才可以引用(主要就是使用#include)  
  但是extern是程序级的,你不必显式的引用文件的,但需要使用extern