c 中 declspec 的用法

2021-06-22 14:45:10 字數 4416 閱讀 9567

語法說明:

__declspec ( extended-decl-modifier-seq )

擴充套件修飾符:

1:align(#) 

用__declspec(align(#))精確控制使用者自定資料的對齊方式 ,#是對齊值。

e.g__declspec(align(32)) 

struct str1;

***它與#pragma pack()是一對兄弟,前者規定了對齊的最小值,後者規定了對齊的最大值。同時出現時,前者優先順序高。 __declspec(align())的乙個特點是,

它僅僅規定了資料對齊的位置,而沒有規定資料實際占用的記憶體長度,當指定的資料被放置在確定的位置之後,其後的資料填充仍然是按照#pragma pack規定的方式填充的,這時候類/結構的實際大小和記憶體格局的規則是這樣的:在__declspec(align())之前,資料按照#pragma pack規定的方式填充,如前所述。當

遇到__declspec(align())的時候,首先尋找距離當前偏移向後最近的對齊點(滿足對齊長度為max(資料自身長度,指定值)),然後把被指定的資料型別從這個

點開始填充,其後的資料型別從它的後面開始,仍然按照#pragma pack填充,直到遇到下乙個__declspec(align())。當所有資料填充完畢,把結構的整體對

齊數值和__declspec(align())規定的值做比較,取其中較大的作為整個結構的對齊長度。 特別的,當__declspec(align())指定的數值比對應型別長度小

的時候,這個指定不起作用。

2: allocate("segname") 

用__declspec(allocate("segname")) 宣告乙個已經分配了資料段的乙個資料項。它和#pragma 的code_seg, const_seg, data_seg,section,init_seg配合使用,segname必須有這些東東宣告。

e.g#pragma data_seg("share_data")

int a = 0;

int b;

#pragma data_seg() __declspec(allocate("share_data")) int c = 1;

__declspec(allocate("share_data")) int d;

3. deprecated  

用__declspec(deprecated ) 說明乙個函式,型別,或別的識別符號在新的版本或未來版本中不再支援,你不應該用這個函式或型別。它和#pragma deprecated作用一樣。

e.g#define my_text "function is deprecated"

void func1(void) {}

__declspec(deprecated) void func1(int)

__declspec(deprecated("** this is a deprecated function **")) void func2(int)

__declspec(deprecated(my_text)) void func3(int)  

int main()

4.dllimport 和dllexport 

用__declspec(dllexport),__declspec(dllimport)顯式的定義dll介面給呼叫它的exe或dll檔案,用 dllexport定義的函式不再需要(.def)檔案宣告這些函式介面了。注意:若在dll中定義了模板類那它已經隱式的進行了這兩種宣告,我們只需在 呼叫的時候例項化即可,呵呵。

e.g 常規方式dll中

class ___declspec(dllexport) 

testdll; 

~testdll(){};

};呼叫客戶端中宣告

#import comment(lib, "**.lib)

class ___declspec(dllimportt) 

testdll;  

~testdll(){};

}; e.g 模板類:dll中

template

class test;

~test(){};

}呼叫客戶端中宣告

int main()

5. jitintrinsic

用__declspec(jitintrinsic)標記乙個函式或元素為64位公共語言執行時。具體用法未見到。

6. __declspec( naked )  

對於沒有用naked宣告的函式一般編譯器都會產生儲存現場(進入函式時編譯器會產生**來儲存esi,edi,ebx,ebp暫存器 ——prolog)和清除現場(退出函式時則產生**恢復這些暫存器的內容——epilog) **,而對於用naked宣告的函式一般不會產生這些**,這個屬性對於寫裝置驅動程式非常有用,我們自己可以寫這樣乙個過程,它僅支援x86 。naked只對函式有效,而對型別定義無效。對於乙個標誌了naked的函式不能產生乙個內聯函式即時使用了__forceinline 關鍵字。

e.g__declspec ( naked ) func()

/* function body */

__asm    /* epilog */

}7. restrict 和 noalias 

__declspec(restrict) 和 __declspec(noalias)用於提高程式效能,優化程式。這兩個關鍵字都僅用於函式,restrict針對於函式返回指標,restrict 說明函式返回值沒有被別名化,返回的指標是唯一的,沒有被別的函式指標別名花,也就是說返回指標還沒有被用過是唯一的。編譯器一般會去檢查指標是否可用和 是否被別名化,是否已經在使用,使用了這個關鍵字,編譯器就不在去檢查這些資訊了。noalias 意味著函式呼叫不能修改或引用可見的全域性狀態並且僅僅修改指標引數直接指向的記憶體。如果乙個函式指定了noalias關鍵字,優化器認為除引數自生之外, 僅僅引數指標第一級間接是被引用或修改在函式內部。可見全域性狀態是指沒有定義或引用在編碼範圍外的全部資料集,它們的直至不可以取得。編碼範圍是指所有源 檔案或單個原始檔。其實這兩個關鍵字就是給編譯器了一種保證,編譯器信任他就不在進行一些檢查操作了。

e.g#include

#include

#define m 800#define n 600#define p 700float * mempool, * memptr;

__declspec(restrict) float * ma(int size)

__declspec(restrict) float * init(int m, int n)

;這是vc裡面的一段**,我們可以看出編譯release版本時,在cobject前是__declspec(novtable),在debug版本沒有這個限制。

e.g#include

struct __declspec(novtable) x

;struct y : public x 

};12.selectany的作用 *** 

__declspec(selectany)可以讓我們在.h檔案中初始化乙個全域性變數而不是只能放在.cpp中。比如有乙個類,其中有乙個靜態變數,那 麼我們可以在.h中通過類似" __declspec(selectany) type class::variable = value; "這樣的**來初始化這個全域性變數。既是該.h被多次include,鏈結器也會為我們剔除多重定義的錯誤。這個有什麼好處呢,我覺得對於 teamplate的程式設計會有很多便利。

e.gclass test

;__declspec(selectany) int test::t = 0; 

13.thread  

thread 用於宣告乙個執行緒本地變數. __declspec(thread)的字首是microsoft新增給visual c++編譯器的乙個修改符。它告訴編譯器,對應的變數應該放入可執行檔案或dll檔案中它的自己的節中。__declspec(thread)後面的變數 必須宣告為函式中(或函式外)的乙個全域性變數或靜態變數。不能宣告乙個型別為__declspec(thread)的區域性變數。

e.g__declspec(thread) 

class x x; // x is a thread objectx y; // y is not a thread object 

14.uuid__declspec(uuid)

用於編譯器關聯乙個guid到乙個有uuid屬性的類或結構的宣告或者定義.

e.gstruct __declspec(uuid("00000000-0000-0000-c000-000000000046")) iunknown;struct __declspec(uuid("")) idispatch;我們可以在mfc中檢視原始碼.:)

c 中 declspec 的用法

語法說明 declspec extended decl modifier seq 擴充套件修飾符 1 align 用 declspec align 精確控制使用者自定資料的對齊方式 是對齊值。e.g declspec align 32 struct str1 它與 pragma pack 是一對兄弟...

c 中 declspec 的用法

語法說明 declspec extended decl modifier seq 擴充套件修飾符 1 align 用 declspec align 精確控制使用者自定資料的對齊方式 是對齊值。e.g declspec align 32 struct str1 它與 pragma pack 是一對兄弟...

收藏 declspec關鍵字詳細用法

declspec用於指定所給定型別的例項的與microsoft相關的儲存方式。其它的有關儲存方式的修飾符如static與extern等是c和c 語言的ansi規範,而 declspec是一種擴充套件屬性的定義。擴充套件屬性語法簡化並標準化了c和c 語言關於microsoft的擴充套件。用法 decl...