cc條件編譯
『壹』 vs中debug和release版本的區別
vs中的程序有debug和release兩個版本。
1、版本不同
Debug通常稱為調試版本,通過一系列編譯選項的配合,編譯的結果通常包含調試信息,而且不做任何優化,以為開發人員提供強大的應用程序調試能力。
而Release通常稱為發布版本,是為用戶使用的,一般客戶不允許在發布版本上進行調試。
2、運行效果不同
debug程序通常比release程序要慢,尤其是處理視頻方便release要比debug快很多。
3、演算法不同
debug跟release在初始化變數時所做的操作是不同的,debug是將每個位元組位都賦成0xcc, 而release的賦值近似於隨機。
(1)cc條件編譯擴展閱讀:
二者的編譯選項。
Debug 版本:
/Od 關閉優化開關
/D "_DEBUG" 相當於 #define _DEBUG,打開編譯調試代碼開關(主要針對assert函數)
/ZI 創建 Edit and continue(編輯繼續)資料庫,這樣在調試過程中如果修改了源代碼不需重新編譯
/GZ 可以幫助捕獲內存錯誤
/Gm 打開最小化重鏈接開關,減少鏈接時間
Release 版本:
/MD /ML 或 /MT 使用發布版本的運行時刻函數庫
/O1 或 /O2 優化開關,使程序 最小或最快
/D "NDEBUG" 關閉條件編譯調試代碼開關(即不編譯assert函數)
/GF 合並重復的字元串,並將字元串常量放到只讀內存,防止被修改
可以理解Debug 和 Release 並沒有本質的界限,他們只是一組編譯選項的集合,編譯器只是按照預定的選項行動。可以修改這些選項,從而得到優化過的調試版本或是帶跟蹤語句的發布版本。
『貳』 C語言編譯原理
編譯共分為四個階段:預處理階段、編譯階段、匯編階段、鏈接階段。
1、預處理階段:
主要工作是將頭文件插入到所寫的代碼中,生成擴展名為「.i」的文件替換原來的擴展名為「.c」的文件,但是原來的文件仍然保留,只是執行過程中的實際文件發生了改變。(這里所說的替換並不是指原來的文件被刪除)
2、匯編階段:
插入匯編語言程序,將代碼翻譯成匯編語言。編譯器首先要檢查代碼的規范性、是否有語法錯誤等,以確定代碼的實際要做的工作,在檢查無誤後,編譯器把代碼翻譯成匯編語言,同時將擴展名為「.i」的文件翻譯成擴展名為「.s」的文件。
3、編譯階段:
將匯編語言翻譯成機器語言指令,並將指令打包封存成可重定位目標程序的格式,將擴展名為「.s」的文件翻譯成擴展名為「.o」的二進制文件。
4、鏈接階段:
在示例代碼中,改代碼文件調用了標准庫中printf函數。而printf函數的實際存儲位置是一個單獨編譯的目標文件(編譯的結果也是擴展名為「.o」的文件),所以此時主函數調用的時候,需要將該文件(即printf函數所在的編譯文件)與hello world文件整合到一起,此時鏈接器就可以大顯神通了,將兩個文件合並後生成一個可執行目標文件。
『叄』 多個文件的條件編譯,需要注意些什麼
不能在同一個文件中包含頭文件兩次。一般不會犯這種錯誤,但是當使用包含了一個頭文件的文件時有可能在不知情的情況下犯這個錯誤。
使用預處理器指令#ifndef來解決上面的問題。語名#ifndef hyong…..#endi表示僅當以前沒有使用預處理器編譯指令#define定義的名稱hyong時才處理#ifndef….#endif之間的語句。#define通常創建符號常量,比如#define H 3;把常量3定義為名字H,但只使用#define就能創建名稱,比如#define H;就創建了一個名稱H。完整的#ifndef….#endif語句的例子如下:#ifndef HY #define HY void g(); #endif;該語句的執行順序為:編譯器首先遇到該頭文件時,名稱HY沒有被定義,這時編譯器就將查看#ifndef….#endif之間的內容,並讀取到#define HY這一行。如果在同一文件中遇到包含該頭文件的代碼時,編譯器就知道HY這個名字已經被#define定義了,從而跳過#ifndef….#endif之間的內容。注意這種方法並不能防止頭文件被包含兩次,而只是讓他忽略除第一次包含之外的所有內容。
上面的內容節選自本人文庫里的文章《C++名稱空間與作用域專題》,希望對你有幫助,如果你對預處理器不了解,可以再去下載本人的另一篇文章《C++宏,預處理器,RTTI,typeid與強制類型轉換專題》