c++中__declspec用法總結

來源:互聯網
上載者:User
c++中__declspec用法總結原文地址:http://pangpengzhouwenwen.blog.163.com/blog/static/3007819220081182742178/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; /* will not inline*/ }; 在類中聲明一個函數不需要內聯。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()調用。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.