#ifdef __cplusplus extern "C" { #endif extern double reciprocal (int i); #ifdef __cplusplus } #endif
看到了如上一段代码(《Advance Linux Programming》 代码列表1.3),从如下几个方面解读一下:函数
#ifdef xxx 至关于#if defined(xxx),用于条件编译,若xxx已经被宏定义,那么编译包括其后的各行,直到遇到#endif,#elif,#else语句为止。spa
__cplusplus是C++的自定义宏,若是定义了这个宏说明这是一段C++代码。blog
以上代码的意思就是若是这是一个cpp文件,那么编译器就执行extern "C"{}语句。ip
另外在C/C++中经常使用#ifndef xxx/#endif来避免重复的定义,#ifndef xxx至关于#if !defined(xxx)。内存
extern用来声明变量,该关键字告诉编译器,其声明的变量和函数能够在本模块使用。ci
用extern时仅仅声明变量而不分配内存空间。在一个项目中函数,变量等在全部源文件中必须保持一致,除非指定定义为局部的,全局变量在全部模块中只能定义一次,能够声明屡次,但声明类型必须保持一致。编译器
注:C语言中的定义和声明:源码
声明:io
extern int x; extern int g(int); int f(int, int);
声明只指定标识符,不分配空间。编译
函数的声明能够省略extern关键字,但加上extern关键字能够知道该函数可能在其余模块定义过。
定义:
int x; int g(int x, int y){ return x + y;}
定义是对声明的实现或实例化。
C和C++编译的区别:C++为了支持函数重载,在将代码编译到二进制文件后,函数fun(int)的函数名其实已经变成了相似fun_int这种形式,这时调用fun()函数如fun(2)就对应fun_int(2),而在C语言中是没有重载的,这样C文件在和C++混合编译的时候就会报链接错误。
"C"表示了一种编译和链接的规约,extern "C"则给代码指定了这种规约,并且不影响语义。函数声明中声明指定了extern "C",仍要遵照C++的语法规则,如类型检测参数转换等。
若是有多句代码须要加上extern "C",能够将它们放到extern "C" {}中。
《Advanced Linux Programming》中第一节的示例就用了extern "C"实现了在C语言中调用C++函数:
代码列表 1.1 ( main.c ) C源码—— main.c
#include <stdlib.h> #include <stdio.h> #include “reciprocal.hpp” int main (int argc, char **argv) { int i;
i = atoi (argv[1]); printf (“The reciprocal of %d is %g\n”, i, reciprocal (i)); return 0; }
代码列表 1.2 ( reciprocal.cpp ) C++ 源码—— reciprocal.cpp
#include <cassert> #include “reciprocal.hpp” double reciprocal (int i) { // i 不能为 0 assert (i != 0); return 1.0/i; }
代码列表 1.3 ( reciprocal.hpp )包含文件—— reciprocal.hpp
#ifdef __cplusplus extern "C" { #endif extern double reciprocal (int i); #ifdef __cplusplus } #endif