c++中__declspec用法總結

1. __declspec(align(16)) struct SS{ int a,b; };
它與#pragma pack()是一對兄弟,前者規定了對齊的最小值,後者規定了對齊的最大值。同時出現時,前者優先級高。 __declspec(align())的一個特點是,它僅僅規定了數據對齊的位置,而沒有規定數據實際佔用的內存長度,當指定的數據被放置在確定的位置之後,其後的數據填充仍然是按照#pragma pack規定的方式填充的,這時候類/結構的實際大小和內存格局的規則是這樣的:在__declspec(align())之前,數據按照#pragma pack規定的方式填充,如前所述。當遇到__declspec(align())的時候,首先尋找距離當前偏移向後最近的對齊點(滿足對齊長度爲max(數據自身長度,指定值)),然後把被指定的數據類型從這個點開始填充,其後的數據類型從它的後面開始,仍然按照#pragma pack填充,直到遇到下一個__declspec(align())。當所有數據填充完畢,把結構的整體對齊數值和__declspec(align())規定的值做比較,取其中較大的作爲整個結構的對齊長度。 特別的,當__declspec(align())指定的數值比對應類型長度小的時候,這個指定不起作用。

2. #pragma section("segname",read)
/ __declspec(allocate("segname")) int i = 0;
/ int main(){ return 1;};
此關鍵詞必須跟隨code_seg,const_seg,data_seg,init_seg,section關鍵字之後使用,以上例子使用了section關鍵字。使用此關鍵字將告知編譯器,其後的變量間被分配在那個數據段。

3. __declspec(deprecated(MY_TEXT)) void func(int) {}
與pragma deprecated()相同。此聲明後,如果在同一作用域中使用func(int)函數,將被提醒c4996警告。

4. __declspec( dllimport ) declarator
& __declspec( dllexport ) declarator
無須多說,此二關鍵字用於導入導出外接元素。

5. __declspec(jitintrinsic)
用於標記一個函數或元素爲64位公共語言運行時。具體用法未見到。

6. __declspec( naked ) int func( formal_parameters ) {}
此關鍵字僅用於x86系統,多用於硬件驅動。此關鍵字可以使編譯器在生成代碼時不包含任何註釋或標記。僅可以對函數的定義使用,不能用於數據聲明、定義,或者函數的聲明。

7. __declspec(restrict) float * init(int m, int n) {};
& __declspec(noalias) void multiply(float * a, float * b, float * c) {};// 優化必用!
__declspec(restrict)僅適用於返回指針的函數聲明,如 __declspec(restrict) void *malloc(size_t size);restrict declspec 適用於返回非別名指針的函數。此關鍵字用於 malloc 的 C 運行時庫實現,因爲它決不會返回已經在當前程序中使用的指針值(除非您執行某個非法操作,如在內存已被釋放之後使用它)。restrict declspec 爲編譯器提供執行編譯器優化的更多信息。對於編譯器來說,最大的困難之一是確定哪些指針會與其他指針混淆,而使用這些信息對編譯器很有幫助。有必要指出,這是對編譯器的一個承諾,編譯器並不對其進行驗證。如果您的程序不恰當地使用 restrict declspec,則該程序的行爲會不正確。 __declspec(noalias)也是僅適用於函數,它指出該函數是半純粹的函數。半純粹的函數是指僅引用或修改局部變量、參數和第一層間接參數。此 declspec 是對編譯器的一個承諾,如果該函數引用全局變量或第二層間接指針參數,則編譯器會生成將中斷應用程序的代碼。

8. class X {
/ __declspec(noinline) int mbrfunc() { return 0; };
在類中聲明一個函數不需要內聯。

9. __declspec(noreturn) extern void fatal () {}
不需要返回值。

10. void __declspec(nothrow) __stdcall f2();
不存在異常拋出。

11. struct __declspec(novtable) X { virtual void mf(); };
/ struct Y : public X {void mf() {printf_s("In Y/n");}};
此關鍵字標記的類或結構不能直接實例化,否則將引發AV錯誤(access violation)。此關鍵字的聲明將阻止編譯器對構造和析構函數的vfptr的初始化。可優化編譯後代碼大小。

12. struct S { int i;
/ void putprop(int j) { i = j; }
/ int getprop() { return i; }
/ __declspec(property(get = getprop, put = putprop)) int the_prop;};
此關鍵字與C#中get & set屬性相同,可定義實現針對一個字段的可讀或可寫。以上例子,可以使用(如果實例化S爲ss)如:ss.the_prop = 156;(此時,ss.i == 156)接着如果:cout<< s.the_prop;(此時將調用getprop,使返回156)。

13. __declspec(selectany)(轉)
在MFC,ATL的源代碼中充斥着__declspec(selectany)的聲明。selectany可以讓我們在.h文件中初始化一個全局變量而不是隻能放在.cpp中。比如有一個類,其中有一個靜態變量,那麼我們可以在.h中通過類似__declspec(selectany) type class::variable = value; 這樣的代碼來初始化這個全局變量。既是該.h被多次include,鏈接器也會爲我們剔除多重定義的錯誤。對於template的編程會有很多便利。

14. __declspec(thread) int in_One_Thread;
聲明in_One_Thread爲線程局部變量並具有線程存儲時限,以便鏈接器安排在創建線程時自動分配的存儲。

15. struct __declspec(uuid("00000000-0000-0000-c000-000000000046")) IUnknown;
將具有唯一表示符號的已註冊內容聲明爲一個變量,可使用__uuidof()調用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章