【文章摘要】
Microsoft Visual C++是微軟公司推出的、在Windows下的可視化集成編程系統,也是廣大軟件工程師使用得比較多的一款編程軟件。本文主要講述Visual C++編譯器常用的選項設置,爲大家全面掌握該軟件以進行軟件開發工作提供了有益的參考。
【關鍵詞】
Visual C++ 選項設置 編譯 調試
一、前言
Microsoft Visual C++是Microsoft公司推出的開發Win32環境程序,面向對象的可視化集成編程系統。它不但具有程序框架自動生成、靈活方便的類管理、代碼編寫和界面設計集成交互操作、可開發多種程序等優點,而且通過簡單的設置就可使其生成的程序框架支持數據庫接口、OLE2、WinSock網絡和3D控制界面等。
但是,大多數編程人員只是使用了其基本功能,沒有對之進行深入的瞭解,如不知道Visual C++編譯器常用選項的設置就是一例。通過閱讀相關資料,作者對Visual C++編譯器常用選項設置進行了總結,希望能夠對大家所從事的研發工作有所幫助。
二、 編譯參數的設置
這主要是通過IDE的菜單項“Project->Settings->C/C++”來完成的。如圖1所示。
圖1 “Project Settings”的示意圖1
我們一般通過修改這一頁上的“Category”中的各項來完成編譯參數的設置。“Category”中共有8個選項,包括:General、C++ Language、Code Generation、Customize、Listing Files、Optimizations、Precompiled Headers和Preprocessor。以下分別介紹在每個參數下的配置情況。
1. General
當“Category”一欄選擇“General”時,界面如圖1所示。其它各欄的介紹如表1所示。
表1 “General”下的配置介紹
名稱 |
功能簡介 |
Warning level |
用來控制警告信息,其中Level 1是最嚴重的級別。 |
Optimizations |
是代碼優化,可以在Category的Optimizations項中進行更細的設置。 |
Warnings as errors |
將警告信息當作錯誤處理。 |
Generate browse info |
用以生成.sbr文件,記錄類、變量等符號信息,可以在Category的Listing Files項中進行更多的設置。 |
Debug info |
生成調試信息,包括: 1) None:不產生任何調試信息(編譯比較快)。 2) Line Numbers Only:僅生成全局的和外部符號的調試信息到.OBJ文件或.EXE文件,減小目標文件的尺寸。 3) C7 Compatible:記錄調試器用到的所有符號信息到.OBJ文件和.EXE文件。 4) Program Database:創建.PDB文件記錄所有調試信息。 5) Program Database for "Edit & Continue:創建.PDB文件記錄所有調試信息,並且支持調試時編輯。 |
2. C++ Language
當“Category”一欄選擇“C++ Language”時,界面如圖2所示。其它各欄的介紹如表2所示。
圖2 “Project Settings”的示意圖2
表2 “C++ Language”下的配置介紹
名稱 |
功能簡介 |
Pointer-to-member representation |
用來設置類定義/引用的先後關係,一般爲Best-Case Always表示在引用類之前該類肯定已經定義了。 |
Enable Exception Handling |
進行同步的異常處理。 |
Enable Run-Time Type Information |
迫使編譯器增加代碼在運行時進行對象類型檢查。 |
Disable Construction Displacements |
設置類構造/析構函數調用虛函數問題。 |
3. Code Generation
當“Category”一欄選擇“Code Generation”時,界面如圖3所示。其它各欄的介紹如表3所示。
圖3 “Project Settings”的示意圖3
表3 “Code Generation”下的配置介紹
名稱 |
功能簡介 |
Processor |
表示代碼指令優化,可以爲80386、80486、Pentium、Pentium Pro,或者Blend表示混合以上各種優化。 |
Use run-time library |
用以指定程序運行時使用的運行時庫(單線程或多線程,Debug版本或Release版本),有一個原則就是,一個進程不要同時使用幾個版本的運行時庫。具體包括: 1) Single-Threaded:靜態連接LIBC.LIB庫。 2) Multithreaded:靜態連接LIBCMT.LIB庫。 3) Multithreaded DLL:動態連接MSVCRT.DLL庫。 4) Debug Single-Threaded:靜態連接LIBCD.LIB庫。 5) Debug Multithreaded:靜態連接LIBCMTD.LIB庫。 6) Debug Multithreaded DLL:動態連接MSVCRTD.DLL庫。連接了單線程庫就不支持多線程調用,連接了多線程庫就要求創建多線程的應用程序。 |
Calling convention |
可以用來設定調用約定,有三種:__cdecl、__fastcall和__stdcall。各種調用約定的主要區別在於,函數調用時,函數的參數是從左到右壓入堆棧還是從右到左壓入堆棧;在函數返回時,由函數的調用者來清理壓入堆棧的參數還是由函數本身來清理;以及在編譯時對函數名進行的命名修飾(可以通過Listing Files看到各種命名修飾方式)。 |
Struct member alignment |
用以指定數據結構中的成員變量在內存中是按幾字節對齊的,根據計算機數據總線的位數,不同的對齊方式存取數據的速度不一樣。這個參數對數據包網絡傳輸等應用尤爲重要,不是存取速度問題,而是數據位的精確定義問題,一般在程序中使用#pragma pack來指定。 |
4. Customize
當“Category”一欄選擇“Customize”時,界面如圖4所示。其它各欄的介紹如表4所示。
圖4 “Project Settings”的示意圖4
表4 “Customize”下的配置介紹
名稱 |
功能簡介 |
Disable Language Extensions |
表示不使用微軟爲標準C做的語言擴展。 |
Enable Function-Level Linking |
告訴編譯器將各個函數按打包格式編譯。 |
Eliminate Duplicate Strings |
主要用於字符串優化(將字符串放到緩充池裏以節省空間),使用這個參數,使得: char *sBuffer = "This is a character buffer"; char *tBuffer = "This is a character buffer"; sBuffer和tBuffer指向的是同一塊內存空間。 |
Enables minimal rebuild |
通過保存關聯信息到.IDB文件,使編譯器只對最新類定義改動過的源文件進行重編譯,提高編譯速度。 |
Enable Incremental Compilation |
同樣通過.IDB文件保存的信息,只重編譯最新改動過的函數。 |
Suppress Startup Banner and Information Messages |
用以控制參數是否在output窗口輸出。 |
5. Listing Files
當“Category”一欄選擇“Listing Files”時,界面如圖5所示。其它各欄的介紹如表5所示。
圖5 “Project Settings”的示意圖5
表5 “Listing Files”下的配置介紹
名稱 |
功能簡介 |
Generate browse info |
其功能上面已經提到過,這裏可以進行更多的設置。 |
Exclude Local Variables from Browse Info |
表示是否將局部變量的信息放到.SBR文件中。 |
Listing file type |
可以設置生成的列表信息文件的內容:Assembly-Only Listing僅生成彙編代碼文件(.ASM擴展名),Assembly With Machine Code生成機器代碼和彙編代碼文件(.COD擴展名),Assembly With Source Code生成源代碼和彙編代碼文件(.ASM擴展名),Assembly, Machine Code,and Source生成機器碼、源代碼和彙編代碼文件(.COD擴展名)。 |
Listing file name |
爲生成的信息文件的路徑,一般爲Debug或Release目錄下,生成的文件名自動取源文件的文件名。 |
6. Optimizations
當“Category”一欄選擇“Optimizations”時,界面如圖6所示。其它各欄的介紹如表6所示。
圖6 “Project Settings”的示意圖6
表6 “Optimizations”下的配置介紹
名稱 |
功能簡介 |
Maximize Speed |
生成最快速的代碼。 |
Minimize Size |
生成最小尺寸的程序。 |
Customize |
Assume No Aliasing 不使用別名(提高速度); Assume Aliasing Across Function Calls 僅函數內部不使用別名; Global Optimizations 全局優化; Generate Intrinsic Functions 使用內部函數替換一些函數調用(提高速度); Improve Float Consistency 浮點運算方面的優化; Favor Small Code 程序(exe或dll)尺寸優化優先於代碼速度優化; Frame-Pointer Omission 不使用幀指針,以提高函數調用速度; Full Optimization 組合了幾種參數,以生成最快的程序代碼。 |
Inline function expansion |
內聯函數擴展的三種優化(使用內聯可以節省函數調用的開銷,加快程序速度): Disable不使用內聯; Only __inline,僅函數定義前有inline或__inline標記使用內聯; Any Suitable,除了inline或__inline標記的函數外,編譯器“覺得”應該使用內聯的函數,都使用內聯。 |
7. Precompiled Headers
當“Category”一欄選擇“Precompiled Headers”時,界面如圖7所示。
圖7 “Project Settings”的示意圖7
預編譯頭文件的設置。使用預編譯可以提高重複編譯的速度。IDE一般將一些公共的、不大變動的頭文件(比如afxwin.h等)集中放到stdafx.h中,這一部分代碼就不必每次都重新編譯(除非是Rebuild All)。
8. Preprocessor
當“Category”一欄選擇“Preprocessor”時,界面如圖8所示。
圖8 “Project Settings”的示意圖8
可以定義/解除定義一些常量。Additional include directories,可以指定額外的包含目錄,一般是相對於本項目的目錄,如……\\Include。
三、 連接參數的設置
這主要是通過IDE的菜單項“Project->Settings->Link”來完成。
1. General
當“Category”一欄選擇“General”時,界面如圖9所示。
圖9 “Project Settings”的示意圖9
可以設置生成的文件路徑、文件名,連接的庫文件等。
Generate debug info:生成Debug信息到.PDB文件(具體格式可以在Category->Debug中設置)。
Ignore All Default Libraries:放棄所有默認的庫連接。
Link Incrementally:通過生成. ILK文件實現遞增式連接以提高後續連接速度,但一般這種方式下生成的文件(EXE或DLL)較大。
Generate Mapfile:生成.MAP文件記錄模塊相關信息。
Enable Profiling:這個參數通常與Generate Mapfile參數同時使用,而且如果產生Debug信息的話,不能用.PDB文件,而且必須用Microsoft Format。
2. Customize
當“Category”一欄選擇“Customize”時,界面如圖10所示。
圖10 “Project Settings”的示意圖10
在這裏可以進行使用程序數據庫文件的設置。
Force File Output:強制產生輸出文件(EXE或DLL)。
Print Progress Messages:可以將連接過程中的進度信息輸出到Output窗口。
3. Debug
當“Category”一欄選擇“Debug”時,界面如圖11所示。
圖11 “Project Settings”的示意圖11
在這裏設置是否生成調試信息,以及調試信息的格式。
格式可以有Microsoft Format、COFF Format(Common Object File Format)和Both Formats三種選擇。
Separate Types表示將Debug格式信息以獨立的.PDB文件存放,還是直接放在各個源文件的.PDB文件中。選中的話,表示採用後者的方式,這種方式調試啓動比較快。
4. Input
當“Category”一欄選擇“Input”時,界面如圖12所示。
圖12 “Project Settings”的示意圖12
這裏可以指定要連接的庫文件和放棄連接的庫文件等。
還可以增加額外的庫文件目錄,一般是相對於本項目的目錄,如..\Lib。
Force Symbol References可以指定連接特定符號定義的庫。
5. Output
當“Category”一欄選擇“Output”時,界面如圖13所示。
圖13 “Project Settings”的示意圖13
Base Address可以改變程序默認的基地址(EXE文件默認爲0x400000,DLL默認爲x10000000),操作系統裝載一個程序時總是試着先從這個基地址開始。
Entry-Point Symbol可以指定程序的入口地址,一般爲一個函數名(且必須採用__stdcall調用約定)。一般Win32的程序,EXE的入口爲WinMain,DLL的入口爲DllEntryPoint;最好讓連接器自動設置程序的入口點。默認情況下,通過一個C的運行時庫函數來實現:控制檯程序採用mainCRTStartup(或wmainCRTStartup)去調用程序的main(或wmain)函數;Windows程序採用WinMainCRTStartup(或 wWinMainCRTStartup)調用程序的WinMain(或wWinMain,必須採用__stdcall調用約定);DLL採用_DllMainCRTStartup調用DllMain函數(必須採用__stdcall調用約定)。
Stack allocations,用以設置程序使用的堆棧大小(請使用十進制),默認爲1兆字節。
Version Information告訴連接器在EXE或DLL文件的開始部分放上版本號。
值得注意的是,上面各個參數是大小寫敏感的;在參數後加上“-”表示該參數無效;各個參數值選項有“*”的表示爲該參數的默認值;可以使用頁右上角的“Reset”按鈕來恢復該頁的所有默認設置。
四、其它一些參數設置
1. Project->Settings->General
界面如圖14所示。
圖14 “Project Settings”的示意圖14
可以設置連接MFC庫的方式(靜態或動態)。如果是動態連接,在軟件發佈時不要忘了帶上MFC的DLL。
2. Project->Settings->Debug
界面如圖15所示。
圖15 “Project Settings”的示意圖15
可以設置調試時運行的可執行文件,以及命令行參數等。
3. Project->Settings->Custom Build
界面如圖16所示。
圖16 “Project Settings”的示意圖16
可以設置編譯/連接成功後自動執行一些操作。比較有用的是,寫COM時希望IDE對編譯通過的COM文件自動註冊,可以如下設置:
Description: Register COM
Commands: regsvr32 /s /c $(TargetPath)
echo regsvr32 exe.time > $(TargetDir)\$(TargetName).trg
Outputs: $(TargetDir)\$(TargetName).trg
4. Tools->Options->Directories
界面如圖17所示。
圖17 “Options”的示意圖
設置系統的Include、Library路徑。
五、一些小竅門(針對Visual C++)
1. 有時候,可能在編譯的時候,計算機突然非法關機了(可能是某人不小心碰了電源或你的內存不穩定等原因所致)。當重啓機器後打開剛纔的項目,重新進行編譯,發現IDE會崩掉。你或許以爲你的編譯器壞了,其實不然(你試試編譯其它項目,還是好的!),這時只要將項目的.ncb、.opt、.aps、.clw文件以及Debug、Release目錄下的所有文件都刪掉,然後重新編譯就行了。
2. 如果你想與別人共享你的源代碼項目,但是把整個項目做拷貝又太大。你完全可以刪掉以下文件:.dsw、.ncb、.opt、.aps、.clw、. plg文件以及Debug、Release目錄下的所有文件。
3. 當你的Workspace中包含多個Project的時候,你可能不能直觀地、一眼看出來哪個是當前項目。可以如下設置:Tools->Options->Format,然後在Category中選擇Workspace window,改變其默認的字體(比如設成Fixedsys)就行了。
4. 如何給已有的Project改名字?將該Project關掉,然後以文本格式打開.dsp文件,替換原來的Project名字即可。
5. VC6對類成員的智能提示功能很有用,但有時候會失靈。你可以先關掉項目,將.clw和.ncb刪掉,然後重新打開項目,點擊菜單項View->ClassWizard,在彈出的對話框中按一下“Add All”按鈕,重新Rebuild All。
六、總結
“工欲善其事,必先利其器”,熟練掌握工具的用法是對軟件工程師的基本要求。在本人剛接手項目的時候,對於Visual C++不是很熟悉,導致被一位老工程師問得摸不着頭腦。後來,我上網查了一點資料,發現自己以前對於Visual C++知之甚少。雖然現在很多開發工程師不用該軟件編程,但瞭解其用法對於開發工程師還是很有好處的。
希望該文能夠對大家有所裨益。
七、參考資料
1. Visual C++編譯器常用選項設置,http://developer.51cto.com/art/200901/106017.htm。
2. Microsoft Visual C++,http://baike.baidu.com/view/100377.htm。