在C++项目开发中,源文件不仅限于.cpp文件,假设我们需要引入第三方的库文件时,而恰巧该库文件是.C文件;我们一般也不会把别人的.C文件改造.CPP文件,那样既耗时也可能会带来意想不到的错误。如果直接把.C文件放到项目中,一般连编译都通不过。最近在项目开发中遇到这样的异常,如图1所示。
出现上述异常原因在于编译器对.C文件和.CPP文件采用了不同的编译方式,现在对编译器的编译方式做个简单的介绍:
1、编译方式
重载是C++的特性之一,而C语言并不支持重载,假设有两个函数int func(int p)、int func(double p)。C++编译器根据符号修饰和符号改编的机制对它们进行修饰,使得函数签名func分别变成_Z4funci、_Z4funcd,用这种方式来实现函数的重载。而对于C语言,C编译器编译func()函数后,其函数名可能变成_func(),并没有C++编译器那么复杂,在C++编译环境中引入C函数,必须用extern “c”进行显示地申明,告诉编译器不要用C++的符号改编的机制对该函数名进行修饰。
2、预编译头
C++编译器对每个cpp文件都是进行单独编译的,而通过#include方式引入的头文件是在预编译阶段直接插到.CPP文件中,最后和.CPP文件一起生成汇编代码文件。然后一个头文件可能被多个.CPP文件包含,这样每次编译一个.CPP文件时,都要对同一个头文件进行一次编译,这样就造成头文件被多次重复编译,浪费了编译时间。因此,C++编译器使用了预编译(precompiled)的方式,预先把这些头文件进行编译,得到一个pch文件(precompiled header),当包含该头文件的.CPP文件被编译时,只需使用该头文件对应的pch文件即可,无需再对头文件进行重复编译。
3 不适用预编译头
从图1中的错信息可知,C++编译器不兼容C文件的预编译头。因此,可以将C文件设置为不适用预编译头。在VS2013中右键单击C文件选择“属性”,在属性窗口左侧的“配置属性”中选择“C/C+±>预编译头”,在右侧的“预编译头”栏中选择“不适用预编译头”,如图2所示。
最后项目顺利编译通过!