const;volatile

注:緩存

  • 因爲從沒有使用過 volatile 這個關鍵詞,因此如下內容中,關於 volatile 的說明可能不是正確的.
    spa

const;volatile

  • 在編譯期看來,const,volatile 是變量的屬性,以下:線程

const volatile int i = 33;
// 編譯期會將 i 看成一個變量,其中"int"代表了該變量的類型,"33"則指定了變量的初始值;
// 而 "const","volatile" 則認爲是變量 i 的屬性,其中
// const 代表變量 i 的值不能夠被修改
// volatile 告訴編譯期每一次讀取 i 的值時都從內存中讀取,而不是從緩存中(如寄存器).

volatile

  • 用來修飾一個變量,告訴編譯期翻譯

    • 每一次對該變量的讀取都是從內存中,而不是從緩存中(如:寄存器).
    • 每一次修改變量的值時,都將新值寫入到內存中,而並非只寫到緩存中.
int i = 10;
int a = i;
sleep(3);
int b = i;

// 則編譯期翻譯的彙編代碼多是:
mov eax,i  ;
mov a,eax  ; 將 i 賦值給 a.
call sleep ; 在此以前可能須要插入參數.
mov b,eax  ; 將 i 賦值給 b.此時直接從寄存器中讀取數據,減小了內存訪問次數.

// 當使用了 volatile 關鍵詞後,即:volatile int i = 33;編譯期翻譯的代碼可能以下:
mov eax,i  ;
mov a,eax  ; 
call sleep ; 
mov eax,i  ; 始終從內存中訪問 i 的值.
mov b,eax  ;

// 第 2 個程序,演示修改變量的值後,將新值寫入到內存的必要性.
int i = 0;
void thread_func(){
    lock(); // 獲取 i 的保護鎖.
    i = i+1;
    unlock();
}
// 則此時編譯器編譯結果多是:
call lock();
mov eax,i;
inc eax
// mov i,eax;//編譯器爲了提升效率而可能不會當即將新值寫入到內存中,因此可能沒有該指令.
call unlock();
// 這樣若 2 個線程都同時執行 thread_func(),在線程 1 獲取鎖,並修改 i 的值,而後釋放鎖;此時線程2看到的 i 將仍然是 0.

const,volatile 與指針

  • int const *iptr = &i;int *const iptrc = &i;這兩個語句的區別,首先要知道 iptr,iptrc 也是一個變量,其類型爲 int* 類型,代表該變量的值是一個地址,指向着一個 int 類型的變量.指針

    • int const *iptr; const 的做用範圍是 *iptr,即此處 const 並非代表 iptr 的值不能夠修改,而是 iptr 指向的 int 類型變量(即 i 的值)不能夠修改.code

    • int * const iptrc; const 的做用範圍是 iptrc,代表變量 iptrc 的值不能夠修改,可是 iptrc 指向的 int 類型變量是能夠修改的,以下:ip

int i = 33;
int const *iptr = &i;
int * const iptrc = &i;
++(*iptr); // 錯誤,increment of read-only location ‘* iptr’
++iptr;    // 正確;
++(*iptrc);// 正確
++iptrc;   // 錯誤,increment of read-only variable ‘iptrc’

  • volatile,const 的修飾範圍爲從 const,volatile 所在的位置到變量名處.以下:內存

int const ci = 33; // const 做用範圍是 ci;代表變量 ci 的值是不能夠修改的.
int const *ciptr = &ci; // const 的做用範圍是"*ciptr",代表 ciptr 指向的 int 類型變量的值是不能夠修改的.
int const * const ciptrc = &ci; 
// 第 1 個 const 的修飾範圍是 *ciptrc,代表 ciptrc 指向的 int 類型變量的值是不能夠修改的.
// 第 2 個 const 的修飾範圍是 ciptrc,代表變量 ciptrc 的值是不能夠修改的.
int const ** ciptrptr = &ciptr;
// const 的修飾範圍是 **ciptrptr,
int const * const *ciptrcptr = &ciptrc;
相關文章
相關標籤/搜索