首先,被它修饰的目标是“extern”的。也就是告诉编译器,其声明的函数和变量可以在本模块或其他模块中使用。通常,在模块的头文件中对本模块提供给其他模块引用的函数和全局变量以关键字extern声明。
其次,被它修饰的目标是“c”,意思是其修饰的变量和函数是按照c语言方式编译和连接的。我们来看看c++中对类似c的函数是怎样编译的。作为一种面向对象的语言,c++支持重载,而过程式语言c则不支持。函数被c++编译后在符号库中的名字与c语言的不同。例如下面两个函数:
1 void foo(int x,int y);
2 void foo(int x,float y);
这个函数编译生成的符号是不相同的,前者可能为_foo_int_int型,后者为_foo_int_float型,这样的名字包含了函数名、函数参数数量及类型信息,c++就是靠这种机制来实现函数重载的。这样,如果在c中连接c++编译的符号时,就会因为找不到符号问题发生连接错误。
如果加extern"c"声明后,模块编译生成foo的目标代码时,就不会对其名字进行特殊处理,采用了c语言的方式,也就是_foo之类,不会加上后面函数参数数量及类型信息相关的一串。因此extern"c‘’是c++编译器提供的与c连接交换指定的符号,用来解决名字匹配问题。