extern可以置于
变量
或者
函数
前,以表示变量或者函数的定义在别的文件中,提示
编译器
遇到此变量和函数时在其他模块中寻找其定义。另外,extern也可用来进行链接指定
所以:如果b.cpp要调用a.c中的函数f,那么在b.cpp中声明extern f的话,b.cpp中使用f(2,3)调用时,会自然地查找_f_int_int,此时会查找不到,因为函数f在a.c(.c后缀说明是C语言,那么按照C标准来编译)编译产生的符号是_f,查找_f_int_int当然查找不到啦。正确的是在b.cpp中声明为 extern "C" f
还有一种情况是C要调用C++的函数,由于C只能按C编译,那么C文件a.c中使用函数f(2,3)时系统查找的字符是_f(当然在a.c中声明了extern f告诉系统f的定义在其他文件或模块中),此时会查找不到,导致调用失败。为什么呢,因为f的定义在b.cpp中,编译时是按照C++标准编译,产生的字符是_f_int_int。此时怎么办呢,因为a.c只能按C编译,我们只能让兼容C的b.cpp把函数f按照C标准变异了。即在b.h中函数f的声明前面加上 extern "C",此时函数f就会强制按照C来编译了产生字符_f了。
extern
是
C/C++
语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。
与
extern
对应的关键字是
static
,被它修饰的全局变量和函数只能在本模块中使用。因此,一个函数或变量只可能被本模块使用时,其不可能被
extern “C”
修饰。
该函数被
C
编译器编译后在符号库中的名字为
_foo
,而
C++
编译器则会产生像
_foo_int_int
之类的名字(不同的编译器可能生成的名字不同,但是都采用了相同的机制,生成的新名字称为
“mangled name”
)。
zlingh:
extern:简单说就是使得在当前cpp或者c文件中的变量或者函数,能被其他文件使用。具体点应该是模块。因为文件的话,在a.cpp中声明函数f但没有具体定义,且在a.cpp的函数g中调用了函数f,此时系统会自动在工程下其他文件中查找函数f的定义。如果使用extern的话,应该是在a.cpp的函数f前要加上extern,此时才会去其他文件找。。。具体可看Transpose工程的例子。
extern加在函数前说明,该函数的定义(实现)可以在本文件也可以在其他文件或者模块中。
通常函数的声明在.h文件中,实现在同名的.cpp中,而且.h文件通常会用来包含。就比如现在又a.h,a.cpp,b.h,b.cpp。a.h中声明了f1,f2,f3等一系列函数,a.cpp中实现了f1,f2,f3登。现在b.cpp中我们想要使用f1,f2,f3这系列函数,一种可以的做法是在b.cpp开头加上include "a.cpp"。但从文件组织上看应该加在b.h。但.h文件包含.cpp进来不太好。是否可以b.h包含a.h就完成我们的工作呢。当然可以,只要在a.h中f1等的声明时前面加上extern。那相当于b.h也加了extern。也就是说告诉系统函数f1等的定义在别的模块或文件中,让系统去找。
extern "C" :C的意思就是说该函数按照来编译,比如函数f,那么编译后会在符号库中产生_f。而如果不加C那么C++编译器会产生像_f_int_int,这两个int说明函数f的形参是两个int,这样做的原因是C++允许函数的重载,两个同名函数,只要形参的个数,形参的类型不一样,那么就会重载。调用的时候比如f(2,3)那么就会在符号库中查找_f_int_int,如果f(2.0,3,4)那么会在符号库中查找_f_float_int_int。