一、预编译
C++的预编译(预处理),是指在C++程序源代码被编译之前,由预处理器对C++程序源代码进行的处理。这个过程并不对程序的源代码进行解析,但它把源代码分割或处理成为特定的符号用来支持宏调用。
程序的编译过程可以分为预处理、编译、汇编三部分,其中预处理是首先执行的过程,预处理过程扫描程序源代码,对其进行初步的转换,产生新的源代码提供给编译器。预处理过程读入源代码之后,会检查代码里包含的预处理指令,完成诸如包含其他源文件、定义宏、根据条件决定编译时是否包含某些代码的工作。
总之,预编译程序的作用就是根据源代码中的预编译指令修改源代码。而预编译程序是由一系列和预编译相关的的命令符组成的。预编译指令以“#”作为起始标志,其后紧跟预编译指令关键字,之后是空格,空格之后是预编译指令的内容。
二、头文件的作用
- 通过头文件调用库功能。很多场合,源码不方便向用户公布,只提供头文件和二进制的库,用户只需按照头文件中的接口调用库功能,而不必关心接口的实现。
- 头文件加强类型安全检查。在接口被实现或使用时与头文件中的不一致,编译器就会报错,大大减轻了调试改错的负担。
三、解决重定义错误
- 原因:头文件中av_ts的定义,同时被多个源文件引用。
举个栗子:
头文件a.h
int a = 10;
源文件b.cpp
#include "a.h"
源文件c.cpp
#include "a.h"
预编译阶段会把a.h中的内容拷贝(说法不严谨)到b.cpp和c.cpp中,编译生成b.obj和c.obj。链接器会把所有的全局变量写到全局符号表。
此时,链接器就会发现b.obj和c.obj中都定义了变量a,所以会出现重定义的错误。
- 解决办法
不要在头文件中定义全局变量或函数。如果定义了全局变量,确保该头文件只被包含一次。如果定义了函数,将该函数声明为inline。