close

Const與Volatile

1.const關鍵字:

簡單來說就是讓宣告變數變成唯讀,通常是為了告訴合作夥伴這個值不要改到,也避免自己去改到他,以減少bug的出現。

接下來來看一些簡單的例子:

A. const char *TEST;

B. char * const TEST;

C. char const *TEST;

D. const char* const TEST;

 

對於此例子我們可以這樣看,const修飾其後面的東西。

例如A,const後面是char * 代表此指標指向的char被變成唯讀,而此指標依然可更動。

例如B,const後面是TEST指標,代表此指標指向的位址是不能變更的,而該位置的值可更動。

例如C,const後面是*TEST,所以如同A。

例如D,顯而易見的兩者都不能更動。

 

2.volatile關鍵字:

通常,volatile關鍵字用來阻止編譯器認為的無法「被代碼本身」改變的代碼(變量/對象)進行優化。如在C語言中,volatile關鍵字可以用來提醒編譯器它後面所定義的變量隨時有可能改變,因此編譯後的程序每次需要存儲或讀取這個變量的時候,都會直接從變量地址中讀取數據。如果沒有volatile關鍵字,則編譯器可能優化讀取和存儲,可能暫時使用暫存器中的值,如果這個變量由別的程序更新了的話,將出現不一致的現象。

 

簡單來說,定義為volatile就是宣稱此變數可能會被意想不到的改掉,如此一來,編譯器就不會去優化這個值了,而用到這個變數十必須要重新讀取這個變量,而不是使用保存在站存器中的備份

我們可以看wiki上舉很好的例子:

----------------------------------------------------------------------------------------------------

C語言中MMIO的例子

在這裡例子中,代碼將foo的值設置為0。然後開始不斷地輪詢它的值直到它變成255

static int foo;
 
void bar(void) {
    foo = 0;
 
    while (foo != 255)
         ;
}

一個執行優化的編譯器會提示沒有代碼能修改foo的值,並假設它永遠都只會是0.因此編譯器將用類似下列的無限循環替換函數體:

void bar_optimized(void) {
    foo = 0;
 
    while (true)
         ;
}

但是,foo可能指向一個隨時都能被計算機系統其他部分修改的地址,例如一個連接到中央處理器的設備的硬體暫存器,上面的代碼永遠檢測不到這樣的修改。如果不使用volatile關鍵字,編譯器將假設當前程序是系統中唯一能改變這個值部分(這是到目前為止最廣泛的一種情況)。 為了阻止編譯器像上面那樣優化代碼,需要使用volatile關鍵字:

static volatile int foo;
 
void bar (void) {
    foo = 0;
 
    while (foo != 255)
        ;
}

這樣修改以後循環條件就不會被優化掉,當值改變的時候系統將會檢測到。

----------------------------------------------------------------------------------------------------

來源:https://zh.wikipedia.org/wiki/Volatile%E5%8F%98%E9%87%8F

 

3.探討volatile和const可否同時存在:

這是面試經常考到的題目,一個參數既可以是const也可以是volatile嗎?

Ans:可以的,假設今天是一個唯讀狀態暫存器,宣告為volatile因為他可能被意想不到的修改掉,宣告為const因為我們的程式不能修改他的值(唯讀)

 

 

另外,最近發現字串的一些存取違規的特性:

未命名  

如附圖:

可看到p是直接存到指定的記憶體位置,r則是指向p的記憶體位置,這都沒問題。

但是q是直接宣告一個指標,指向一串字串,會造成記憶體非法寫入,因為"bbbb"實質上是一個字串常量,而常量通常被編譯器放在唯讀記憶體區,是不可寫入的。

 

 

參考網址:http://bluelove1968.pixnet.net/blog/post/222283705-%E6%AD%A3%E7%A2%BA%E4%BD%BF%E7%94%A8const---%E9%97%9C%E9%8D%B5%E5%AD%97const-%E8%88%87volatile%E7%9A%84%E4%BD%BF%E7%94%A8

arrow
arrow
    文章標籤
    c c++ const volatile
    全站熱搜

    CCW 發表在 痞客邦 留言(0) 人氣()