#include <afxwin.h>
#include <windows.h>
#pragma comment(lib,"msvcrt.lib")//or 工程 / 設置 / 常規 /Microsoft 基礎類(使用 MFC 作爲靜態鏈接庫 or 動態庫)
int main()
{
AfxMessageBox("Simple message box.", 0, 0);
//AfxMessageBox(_T("Simple message box."));
return 0;
}
結果:
在所有的預處理指令中, #pragma 指令可能是最複雜的了,它的作用是設定編譯器的狀態或者是指示編譯器完成一些特定的動作。
#pragma 指令對每個編譯器給出了一個方法 , 在保持與 C 和 C++ 語言完全兼容的情況下 , 給出主機或操作系統專有的特徵。
依據定義 , 編譯指示是機器或操作系統專有的 , 且對於每個編譯器都是不同的。
其格式一般爲 : #pragma para
其中 para 爲參數,下面來看一些常用的參數。
下面就從網上找了一些pragma的用法資料:
(1)message 參數
message 參數是我最喜歡的一個參數,它能夠在編譯信息輸出窗口中輸出相應的信息,
這對於源代碼信息的控制是非常重要的。其使用方法爲:
#pragma message(" 消息文本 ")
當編譯器遇到這條指令時就在編譯輸出窗口中將消息文本打印出來。
當我們在程序中定義了許多宏來控制源代碼版本的時候,我們自己有可能都會忘記有沒有正確的設置這些宏,
此時我們可以用這條指令在編譯的時候就進行檢查。假設我們希望判斷自己有沒有在源代碼的什麼地方定義了 _X86 這個宏 ,
可以用下面的方法 :
#ifdef _X86
#pragma message("_X86 macro activated!")
#endif
我們定義了 _X86 這個宏以後,應用程序在編譯時就會在編譯輸出窗口裏顯示 "_86 macro activated!" 。
我們就不會因爲不記得自己定義的一些特定的宏而抓耳撓腮了。
(2) 另一個使用得比較多的 pragma 參數是 code_seg
格式如:
#pragma code_seg( ["section-name" [, "section-class"] ] )
它能夠設置程序中函數代碼存放的代碼段,當我們開發驅動程序的時候就會使用到它。
(3)#pragma once ( 比較常用 )
只要在頭文件的最開始加入這條指令就能夠保證頭文件被編譯一次,這條指令實際上在 VC6 中就已經有了,
但是考慮到兼容性並沒有太多的使用它。
(4)#pragma hdrstop
表示預編譯頭文件到此爲止,後面的頭文件不進行預編譯。 BCB 可以預編譯頭文件以加快鏈接的速度,
但如果所有頭文件都進行預編譯又可能佔太多磁盤空間,所以使用這個選項排除一些頭文件。
有時單元之間有依賴關係,比如單元 A 依賴單元 B ,所以單元 B 要先於單元 A 編譯。
你可以用 #pragma startup 指定編譯優先級,如果使用了 #pragma package(smart_init) ,
BCB 就會根據優先級的大小先後編譯。
(5)#pragma resource "*.dfm"
表示把 *.dfm 文件中的資源加入工程。 *.dfm 中包括窗體
外觀的定義。
(6)#pragma warning( disable: 4507 34; once: 4385; error: 164 )
等價於:
#pragma warning( disable: 4507 34 ) // 不顯示 4507 和 34 號警告信息
#pragma warning( once: 4385 ) // 4385 號警告信息僅報告一次
#pragma warning( error: 164 ) // 把 164 號警告信息作爲一個錯誤。
同時這個 pragma warning 也支持如下格式:
#pragma warning( push [, n ] )
#pragma warning( pop )
這裏 n 代表一個警告等級 (1---4) 。
#pragma warning( push ) 保存所有警告信息的現有的警告狀態。
#pragma warning( push, n ) 保存所有警告信息的現有的警告狀態,並且把全局警告等級設定爲 n 。
#pragma warning( pop ) 向棧中彈出最後一個警告信息,在入棧和出棧之間所作的一切改動取消。例如:
#pragma warning( push )
#pragma warning( disable: 4705 )
#pragma warning( disable: 4706 )
#pragma warning( disable: 4707 )
//.......
#pragma warning( pop )
在這段代碼的最後,重新保存所有的警告信息 ( 包括 4705 , 4706 和 4707) 。
(7)#pragma comment(...)
該指令將一個註釋記錄放入一個對象文件或可執行文件中。
常用的 lib 關鍵字,可以幫我們連入一個庫文件。如:
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "vfw32.lib")
#pragma comment(lib, "wsock32.lib")
每個編譯程序可以用 #pragma 指令激活或終止該編譯程序支持的一些編譯功能。
例如,對循環優化功能:
#pragma loop_opt(on) // 激活
#pragma loop_opt(off) // 終止
有時,程序中會有些函數會使編譯器發出你熟知而想忽略的警告,
如“ Parameter xxx is never used in function xxx ”,可以這樣:
#pragma warn —100 // Turn off the warning message for warning #100
int insert_record(REC *r)
{ /* function body */ }
#pragma warn +100 // Turn the warning message for warning #100 back on
函數會產生一條有唯一特徵碼 100 的警告信息,如此可暫時終止該警告。
每個編譯器對 #pragma 的實現不同,在一個編譯器中有效在別的編譯器中幾乎無效。可從編譯器的文檔中查看。
補充 —— #pragma pack 與 內存對齊問題
許多實際的計算機系統對基本類型數據在內存中存放的位置有限制,它們會要求這些數據的首地址的值是某個數 k
( 通常它爲 4 或 8) 的倍數,這就是所謂的內存對齊,而這個 k 則被稱爲該數據類型的對齊模數 (alignment modulus) 。
Win32 平臺下的微軟 C 編譯器 (cl.exe for 80x86) 在默認情況下采用如下的對齊規則 :
任何基本數據類型 T 的對齊模數就是 T 的大小,即 sizeof(T) 。比如對於 double 類型 (8 字節 ) ,
就要求該類型數據的地址總是 8 的倍數,而 char 類型數據 (1 字節 ) 則可以從任何一個地址開始。
Linux 下的 GCC 奉行的是另外一套規則 ( 在資料中查得,並未驗證,如錯誤請指正 ):
任何 2 字節大小 ( 包括單字節嗎 ?) 的數據類型 ( 比如 short) 的對齊模數是 2 ,而其它所有超過 2 字節的數據類型
( 比如 long,double) 都以 4 爲對齊模數。
ANSI C 規定一種結構類型的大小是它所有字段的大小以及字段之間或字段尾部的填充區大小之和。
填充區就是爲了使結構體字段滿足內存對齊要求而額外分配給結構體的空間。那麼結構體本身有什麼對齊要求嗎?
有的, ANSI C 標準規定結構體類型的對齊要求不能比它所有字段中要求最嚴格的那個寬鬆,可以更嚴格。
如何使用 c/c++ 中的對齊選項
vc6 中的編譯選項有 /Zp[1|2|4|8|16] , /Zp1 表示以 1 字節邊界對齊,相應的, /Zpn 表示以 n 字節邊界對齊。
n 字節邊界對齊的意思是說,一個成員的地址必須安排在成員的尺寸的整數倍地址上或者是 n 的整數倍地址上,取它們中的最小值。
也就是:
min ( sizeof ( member ), n)
實際上, 1 字節邊界對齊也就表示了結構成員之間沒有空洞。
/Zpn 選項是應用於整個工程的,影響所有的參與編譯的結構。
要使用這個選項,可以在 vc6 中打開工程屬性頁, c/c++ 頁,選擇 Code Generation 分類,在 Struct member alignment 可以選擇。
要專門針對某些結構定義使用對齊選項,可以使用 #pragma pack 編譯指令 :
(1) #pragma pack( [ n ] )
該指令指定結構和聯合成員的緊湊對齊。而一個完整的轉換單元的結構和聯合的緊湊對齊由 /Zp 選項設置。
緊湊對齊用 pack 編譯指示在數據說明層設置。該編譯指示在其出現後的第一個結構或聯合說明處生效。
該編譯指示對定義無效。
當你使用 #pragma pack ( n ) 時 , 這裏 n 爲 1 、 2 、 4 、 8 或 16 。
第一個結構成員之後的每個結構成員都被存儲在更小的成員類型或 n 字節界限內。
如果你使用無參量的 #pragma pack, 結構成員被緊湊爲以 /Zp 指定的值。該缺省 /Zp 緊湊值爲 /Zp8 。
(2) 編譯器也支持以下增強型語法 :
#pragma pack( [ [ { push | pop } , ] [ identifier, ] ] [ n] )
若不同的組件使用 pack 編譯指示指定不同的緊湊對齊 , 這個語法允許你把程序組件組合爲一個單獨的轉換單元。
帶 push 參量的 pack 編譯指示的每次出現將當前的緊湊對齊存儲到一個內部編譯器堆棧中。
編譯指示的參量表從左到右讀取。如果你使用 push, 則當前緊湊值被存儲起來 ;
如果你給出一個 n 的值 , 該值將成爲新的緊湊值。若你指定一個標識符 , 即你選定一個名稱 ,
則該標識符將和這個新的的緊湊值聯繫起來。
帶一個 pop 參量的 pack 編譯指示的每次出現都會檢索內部編譯器堆棧頂的值 , 並且使該值爲新的緊湊對齊值。
如果你使用 pop 參量且內部編譯器堆棧是空的 , 則緊湊值爲命令行給定的值 , 並且將產生一個警告信息。
若你使用 pop 且指定一個 n 的值 , 該值將成爲新的緊湊值。若你使用 p o p 且指定一個標識符 ,
所有存儲在堆棧中的值將從棧中刪除 , 直到找到一個匹配的標識符 , 這個與標識符相關的緊湊值也從棧中移出 ,
並且這個僅在標識符入棧之前存在的緊湊值成爲新的緊湊值。如果未找到匹配的標識符 ,
將使用命令行設置的緊湊值 , 並且將產生一個一級警告。缺省緊湊對齊爲 8 。
pack 編譯指示的新的增強功能讓你編寫頭文件 , 確保在遇到該頭文件的前後的
緊湊值是一樣的。
(3) 棧內存對齊
在 vc6 中棧的對齊方式不受結構成員對齊選項的影響。它總是保持對齊,而且對齊在 4 字節邊界上。
詳細出處: http://www.52rd.com/blog/Detail_RD.Blog_sunhuibo_5025.html