天天看點

預編譯頭 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.

繼續閱讀