VC __declspec關鍵字

來源:互聯網
上載者:User

原文地址:http://hi.baidu.com/henfengduandie/item/f13afbca610c20d696445285VC __declspec關鍵字

align
格式:__declspec(align(n)) declarator
其中,n是對齊參數,其有效值是2的整數次冪(從1到8192位元組),如2,4,8,16,32或64。參數declarator是要設定對齊的資料。
1.使用__declspec(align(n))來精確控制使用者自訂資料的對齊。你可以在定義struct,union,class或聲明變數時使用__declspec(align(n))。
2.不能為函數參數使用__declspec(align(n))。
3.如果未使用__declspec(align(#)),編譯器將根據資料大小按常態範圍對齊。如4位元組整數按4位元組邊界對齊;8位元組double按8位元組邊界對齊。類或結構體中的資料,將取資料本身的自然對齊和#pragma pack(n)設定的對齊係數中的最小值進行對齊。
4.__declspec(align(n))和#pragma pack(n)是一對兄弟,前者規定了對齊係數的最小值,後者規定了對齊係數的最大值。
5.當兩者同時出現時,前者擁有更高的優先順序。即,當兩者同時出現且值矛盾時,後者將不起作用。
6.當變數size大於等於#pragma pack(n)指定的n,而且__declspec(align(n))指定的數值n比對應類型長度小的時候,這個__declspec(align(n))指定將不起作用。
7.當#pragma pack(n)指定的值n大於等於所有資料成員size的時候,這個值n將不起作用。

allocate
格式:__declspec(allocate("segname")) declarator
為資料指定儲存的資料區段。資料區段名必須為以下列舉中的一個:
code_seg
const_seg
data_seg
init_seg
section

appdomain
指定託管程式中的每個應用程式定義域都要有一份指定全域變數或靜態成員變數的拷貝。

deprecated
與#pragma deprecated()的作用相同。用於指定函數的某個重載形式是不推薦的。當在程式中調用了被deprecated修飾的函數時,編譯器將給出C4996警告,並且可以指定具體的警告資訊。該警告資訊可以來源於定義的宏。
例如:
// compile with: /W3
#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() {
   func1();
   func1(1);   // C4996,警告資訊:warning C4996: 'func1': was declared deprecated
   func2(1);   // C4996,警告資訊:warning C4996: 'func2': ** this is a deprecated function **
   func3(1);   // C4996,警告資訊:warning C4996: 'func3': function is deprecated
}

dllimport,dllexport
格式:
__declspec( dllimport ) declarator
__declspec( dllexport ) declarator
分別用來從dll匯入函數,資料,或對象以及從dll中匯出函數,資料,或對象。相當於定義了dll的介面,為它的客戶exe或dll定義可使用的函數,資料,或對象。
將函式宣告成dllexport就可以免去定義模組定義(.DEF)檔案。
dllexport代替了__export關鍵字。
被聲明為dllexport的C++函數匯出時的函數名將會按照C++規則經過處理。如果要求不按照C++規則進行名文書處理,請使用.def檔案或使用extern "C"。

jitintrinsic
格式:__declspec(jitintrinsic)
用於標記一個函數或元素是64位通用語言運行時(CLR)。主要用於Microsoft提供的某些庫中。
使用jitintrinsic會在函數簽名中加入MODOPT(IsJitIntrinsic)。

naked
格式:__declspec(naked) declarator
此關鍵字僅用於x86系統,多用於虛擬設備驅動。此關鍵字可以使編譯器在產生代碼時不包含任何注釋或標記。僅可以對函數的定義使用,不能用於資料聲明、定義,或者函數的聲明。

noalias
僅適用於函數,它指出該函數是半純粹的函數。半純粹的函數是指僅引用或修改局部變數、參數和第一層間接參數。它是對編譯器的一個承諾,如果該函數引用全域變數或第二層間接指標參數,則編譯器會產生中斷應用程式的代碼。

restrict
格式:__declspec(restrict) return_type f();
僅適用於返回指標的函式宣告或定義,如,CRT的malloc函數:__declspec(restrict) void *malloc(size_t size);它告訴編譯器該函數返回的指標不會與任何其它的指標混淆。它為編譯器提供執行編譯器最佳化的更多資訊。對於編譯器來說,最大的困難之一是確定哪些指標會與其它指標混淆,而使用這些資訊對編譯器很有協助。有必要指出,這是對編譯器的一個承諾,編譯器並不對其進行驗證。如果您的程式不恰當地使用__declspec(restrict),則該程式的行為會不正確。

noinline
因為在類定義中定義的成員函數預設都是inline的,__declspec(naked)用於顯式指定類中的某個函數不需要inline(內聯)。如果一個函數很小而且對系統效能影響不大,有必要將其聲明為非內斂的。例如,用於處理錯誤情況的函數。

noreturn
一個函數被__declspec(noreturn)所修飾,那麼它的含義是告訴編譯器,這個函數不會返回,其結果是讓編譯器知道被修飾為__declspec(noreturn)的函數之後的代碼不可到達。
如果編譯器發現一個函數有無傳回值的代碼分支,編譯器將會報C4715警告,或者C2202錯誤資訊。如果這個代碼分支是因為函數不會返回從而無法到達的話,可以使用約定__declspec(noreturn)來避免上述警告或者錯誤。
將一個期望返回的函數約定為__declspec(noreturn)將導致未定義的行為。
在下面的這個例子中,main函數沒有從else分支返回,所以約定函數fatal為__declspec(noreturn)來避免編譯或警告資訊。
__declspec(noreturn) extern void fatal () {}
int main() {
if(1)
   return 1;
else if(0)
   return 0;
else
   fatal();
}

nothrow:
格式:return-type __declspec(nothrow) [call-convention] function-name ([argument-list])
可用於函式宣告。告訴編譯器被聲明的函數以及函數內部調用的其它函數都不會拋出異常。

novtable
可用於任何類聲明中,但最好只用於純介面類,即類本身從不執行個體化。此關鍵字的聲明將阻止編譯器對構造和解構函式的vfptr的初始化。可最佳化編譯後代碼大小。
如果試圖執行個體化一個用__declspec(novtable)聲明的類然後訪問類中成員,則會在運行時產生訪問錯誤(access violation,即AV)。

process
表示你的託管應用程式進程應該擁有一份指定全域變數,靜態成員變數,或所有應用程式定義域共用的靜態本地變數的拷貝。在使用/clr:pure進行編譯時間,應該使用__declspec(process),因為使用/clr:pure進行編譯時間,在預設情況下,每個應用程式定義域擁有一份全域和靜態變數的拷貝。在使用/clr進行編譯時間,不必使用__declspec(process),因為使用/clr進行編譯時間,在預設情況下,每個進程有一份全域和靜態變數的拷貝。
只有全域變數,靜態成員變數,或本地類型的本地靜態變數可以用__declspec(process)修飾。
在使用/clr:pure進行編譯時間,被聲明為__declspec(process)的變數同時也應該聲明為const類型。
如果想每個應用程式定義域擁有一份全域變數的拷貝時,請使用appdomain。

property
格式:
__declspec( property( get=get_func_name ) ) declarator
__declspec( property( put=put_func_name ) ) declarator
__declspec( property( get=get_func_name, put=put_func_name ) ) declarator
該屬性可用於類或結構定義中的非靜態“虛資料成員”。實際上就是做了一個映射,把你的方法映射成屬性,以供訪問。get和put就是屬性訪問的許可權,一個是讀的許可權,一個是寫的許可權。當編譯器看到被property修飾的資料成員出現在成員選擇符("." 或 "->")的右邊的時候,它將把該操作轉換成get或put方法。該修飾符也可用於類或結構定義中的空數組。
用法如下:
struct S {
   int i;
   void putprop(int j) { 
      i = j;
   }
   int getprop() {
      return i;
   }
   __declspec(property(get = getprop, put = putprop)) int the_prop;
};

int main() {
   S s;
   s.the_prop = 5;
   return s.the_prop;
}

selectany
格式:__declspec(selectany) declarator
在MFC,ATL的原始碼中充斥著__declspec(selectany)的聲明。selectany可以讓我們在.h檔案中初始化一個全域變數而不是只能放在.cpp中。比如有一個類,其中有一個靜態變數,那麼我們可以在.h中通過類似__declspec(selectany) type class::variable = value;這樣的代碼來初始化這個全域變數。既是該.h被多次include,連結器也會為我們剔除多重定義的錯誤。對於template的編程會有很多便利。
用法如下:

__declspec(selectany) int x1=1; //正確,x1被初始化,並且對外部可見

const __declspec(selectany) int x2 =2; //錯誤,在C++中,預設情況下const為static;但在C中是正確的,其預設情況下const不為static

extern const __declspec(selectany) int x3=3; //正確,x3是extern const,對外部可見

extern const int x4;
const __declspec(selectany) int x4=4; //正確,x4是extern const,對外部可見

extern __declspec(selectany) int x5; //錯誤,x5未初始化,不能用__declspec(selectany)修飾

class X {
public:
X(int i){i++;};
int i;
};

__declspec(selectany) X x(1); //正確,全域對象的動態初始化

thread
格式:__declspec(thread) declarator
聲明declarator為線程局部變數並具有線程儲存時限,以便連結器安排在建立線程時自動分配的儲存。
線程局部儲存(TLS)是一種機制,在多線程運行環境中,每個線程分配自己的局部資料。在標準多線程程式中,資料是在多個線程間共用的,而TLS是一種為每個線程分配自己局部資料的機制。
該屬性只能用於資料或不含成員函數的類的聲明和定義,不能用於函數的聲明和定義。
該屬性的使用可能會影響DLL的延遲載入。
該屬性只能用於待用資料,包括全域資料對象(static和extern),局部靜態對象,類的待用資料成員;不能用於自動資料對象。
該屬性必須同時用於資料的聲明和定義,不管它的聲明和定義是在一個檔案還是多個檔案。
__declspec(thread)不能用作類型修飾符。
如果在類聲明的同時沒有定義對象,則__declspec(thread)將被忽略,例如:

// compile with: /LD
__declspec(thread) class X
{
public:
   int I; 
} x;   //x是線程對象
X y;   //y不是線程對象

下面兩個例子從語義上來說是相同的:

__declspec(thread) class B {
public:
   int data;
} BObject;   //BObject是線程對象

class B2 {
public:
   int data;
};
__declspec(thread) B2 BObject2;   // BObject2是線程對象

uuid
格式:__declspec( uuid("ComObjectGUID") ) declarator
將具有唯一識別碼號的登入內容聲明為一個變數,可使用__uuidof()調用。
用法如下:
struct __declspec(uuid("00000000-0000-0000-c000-000000000046")) IUnknown;
struct __declspec(uuid("{00020400-0000-0000-c000-000000000046}")) IDispatch;

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.