天天看点

预编译头 error C1010

VS2005报错

fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "stdafx.h"”

  解决方案:

方法一:在include头文件的地方加上#include "stdafx.h"。

方法二:打开此项目的“属性页”对话框。单击“C/C++”文件夹。单击“预编译头”属性页。修改“创建/使用预编译头”属性为“不使用预编译头”。   

对预编译头文件说明如下:

所谓头文件预编译,就是把一个工程(Project)中使用的一些MFC标准头文件(如Windows.H、Afxwin.H)预先编译,以后该工程编译时,不再编译这部分头文件,仅仅使用预编译的结果。这样可以加快编译速度,节省时间。

预编译头文件通过编译stdafx.cpp生成,以工程名命名,由于预编译的头文件的后缀是“pch”,所以编译结果文件是projectname.pch。

编译器通过一个头文件stdafx.h来使用预编译头文件。stdafx.h这个头文件名是可以在project的编译设置里指定的。编译器认为,所有在指令#include "stdafx.h"前的代码都是预编译的,它跳过#include "stdafx. h"指令,使用projectname.pch编译这条指令之后的所有代码。

因此,所有的CPP实现文件第一条语句都是:#include "stdafx.h"。

另外,每一个实现文件CPP都包含了如下语句:

#ifdef _DEBUG

#undef THIS_FILE

static char BASED_CODE THIS_FILE[] = __FILE__;

#endif

这是表示,如果生成调试版本,要指示当前文件的名称。__FILE__是一个宏,在编译器编译过程中给它赋值为当前正在编译的文件名称。

预编译头技术

所谓预编译头,就是把头文件事先编译成一种二进制的中间格式,供后续的编译过程使用。

一、预编译头定义:为了保证编译时快捷,方便c++ 编译器为编译设置的预先编译头文件,VC6 默认是StdAfx.h.但是如果预编头如果发生了变化就需要重新编译。这其实也是大家可能很疑惑的问题:为什么每次只要改动一下stdAfx.h 或 stdAfx.cpp 编译时就会花很长时间。所以对于预编译的头最好少作改动,或是不作改动。

二、预编译头在编译器中的具体体现:–Fp“stdAfx.h” 当然你也可以更改成其他的名字。

三、编译之后的文件放在.pch 文件中,这里不要误认为是.Obj中,这是和其他编译文件的不同之一吧。

四、在makefile中简单的使用预编译技术

obj/i386/debug.obj: debug.c debug.h

        $(CC) –Yc”precomp.h” [email protected] debug.c

obj/i386/OperateReg.obj: OperateReg.c OperateReg.h

        $(CC) –Yu”precomp.h” [email protected] OperateReg.c

obj/i386/WaterMark.obj: WaterMark.c WaterMark.h

        $(CC) –Yu”precomp.h” [email protected] WaterMark.c  

以下同。

其中precomp.h为想预编译的头文件。

五、关于预编译头的一些复杂的使用方法

如:

cl -c -Yc"stuff.h" -Fplevel1.pch level1.cpp       -------------(1)

cl -c -Yu"stuff.h" -Fplevel1.pch -Yc level2.cpp   --------------(2)

level2.cpp的开始是这样的,其中 #pragma hdrstop 表示预编译结束,所以说代码也可以放入预编译头。

#include "stuff.h"

#include "morestuff.h"

#pragma hdrstop("level2.pch")

(1)       建立使用stuff.h 重命名为level1.pch的预编译头。

(2)       在从stuff.h建立的预编译头level1.pch的基础上,参考level2.cpp建立另一个预编译头level2.pch

此时的命名规则参见Yc无参数时的使用方法。

预编译头的其他使用细则请参考msdn。

附:

1、  预编译与guard宏

这是两个根本没有关系的概念,如果说非要找出相同的地方,那就是预编译头对控制重复包含也有一定的帮助。

#ifndef _PLOTBRUSH_

#define _PLOTBRUSH_

---

#endif  // _PLOTBRUSH_

这种guard宏是防止在同一个.c文件中把同一个.h文件包含两次。

即防止出现

#include <windows.h>

#include <windows.h>

的情况的。

而预编译头相当于在全局的角度,来控制那些部分仅被编译一次的问题。

而guard宏只对当前编译单元有效。在1.c中定义了_PLOTBRUSH_对2.c是根本没影响的。

2、  98ddk中build 时,使用build –Z将只编译有改变的源文件。-c 起清除目标文件夹的作用。

如有错漏请指正。

   使用了预编译头技术后,虽然带来了极大地方便,但也造成了一个问题:由于它假定预编译头中包含过的头文件会在所有 cpp 中使用,因此它在编译你的 cpp 的时候,就会将预编译头中已经编译完的部分加载到内存中。如果它突然发现你的 cpp 居然没有包含预编译头,它就会很郁闷,因为它不知道该如何将已编译完的部分从内存中请出去,整个编译过程就会失败。

    因此,如果你使用了预编译头技术,就必须在所有的 cpp 中包含预编译头。MFC 工程中为你建立了一个默认的预编译头 stdafx.h.

继续阅读