pragma (Visual C++)
那與下列這樣的方式有什麼不同呢?
//header.h #pragma once // Your C or C++ code would follow:
//header.h #ifndef HEADER_NAME_H_ #define HEADER_NAME_H_ // Your C or C++ code would follow: #endif
#pragma與#ifndef,#define,#endif都是preprocessing
directives
在ISO/IEC
14882:1998(E)中第16章中有介紹,其中#pragma並沒有制定出一個共通的標準與使用格式
因為在每個編譯器中所制定出的#pragma格式可能不同,所以#pragma相對於#ifndef來說缺乏可攜式。
但如果只在VC的環境下寫程式時就不需要擔心了!
如果考慮到Portability的問題時,建議使用#ifndef,#define,#endif,否則使用那一個都沒有差別。
若對於Portability有興趣的話,可以參考這個網頁:C++ portability guide
//sizeof(int) = 4 , sizeof(char) = 1 , sizeof(double) = 8 struct Student { char sex; unsigned int age; double average; }; int main() { struct Student s1; cout<<(void *)&s1.sex<<endl //0012FF70 <<(void *)&s1.age<<endl //0012FF74 <<(void *)&s1.average<<endl; //0012FF78 cout<<sizeof(Student)<<endl; //16 return 0; }
能判斷出這個Student
struct的大小(size)嗎?是13對嗎?
但若在VC下計算時,不會得到13,因為這牽扯到struct
alignment的問題
在許多機器上為了存取的效率,編譯器配置給8bytes變數的位址必須是8的倍數
,配置給4bytes變數的位址是4的倍數,因為如此,有時需空下幾個bytes的空間
來讓變數放置在存取效率較佳的位址上,而這個調整的動作稱為boundary
alignment(邊界對齊)
或稱為struct alignment(結構對齊)也有人稱為data
alignment(資料對齊)。
注意到上面的程式,s1.age的位址了嗎?並不是0012FF71而是0012FF74,這就是alignment的關係
要如何做調整呢?可以利用#pragma
pack:
#pragma pack(push,1) //將編譯器預設的alignment存入編譯器內部堆疊中,並設定alignment為1 struct Student { char sex; unsigned int age; double average; }; #pragma pack(pop) //將置於編譯器內部堆疊頂端的值pop出來,並指定給alignment
(1)#pragma
pack( push , n
)
這個動作有兩個,有先後動作
Ⅰ. 將目前packing
alignment的值推入(push)編譯器內部堆疊(internal
stack)中
Ⅱ. 將目前的pack
alignment的value設定成n
(2)#pragma
pack(pop)
將在編譯器內部堆疊(internal stack)頂端(top)的值設定給packing alignment
接著重新編譯之後,就會得到13了!
介紹有幫助!
參考資料
(1)MSDN:Pragma
Directives
(2)MSDN:Compiler Warnings That Are Off by Default
(3)Compiler Error Messages
(4)C++ portability guide
Written By James On 2004/09/09