關鍵字volatile和restrict

2022-08-03 05:48:12 字數 1087 閱讀 9703

一、什麼是volatile?什麼是編譯器優化

volatile是乙個型別修飾符,它的主要作用是防止編譯器進行優化。那麼什麼是編譯器優化呢,我們看兩個個例子:

例1:x = 0x04;

x = 0x06;

x = 0x08;

對於硬體來說這是3條指令,依次執行,但是如果讓編譯器進行編譯,則它會忽略前面兩條語句,直接得到 x = 0x08;

int i = 5, j, k;

j = i;

k = i;

編譯器進行編譯時,由於i在第二條和第三條語句之間沒有作為左值存在,所以第三條語句k=i;並沒有真正到i所在的記憶體區域去取得i的值,而是直接取第二條語句儲存在暫存器中的副本。

例2:可見,所謂編譯器優化就是假設了某個變數位址,而volatile的作用就是讓編譯器不去假設變數的值,每次都到記憶體中小心的去訪問變數值。

二、為什麼要使用volatile。

儘管前面的例子告訴我們什麼是編譯器優化,但是編譯器優化會產生錯誤麼?如果不會,就不需要防止編譯器優化了。

編譯器優化是有可能產生錯誤的。因為上面提到,編譯器優化後,對變數取值是有可能會取暫存器中的副本,但是在實際執行時,一些變數的值隨時都有可能被一些未知的因素所改變。下面是幾種變數的值會被改變,需要用到volatile的情況:

(1)並行裝置的硬體暫存器

(2)乙個中斷子程式會用到的非自動變數

(3)多執行緒應用中被幾個執行緒用到的共享變數

首先說明:restrict是c99的關鍵字,c89和c++均不支援。

restrict用於修飾指標,用來告訴編譯器,該指標所指向的物件只能通過該指標訪問,讓編譯器可以進行優化。

比如:

int var = 5;

int *restrict varp = &var;

*varp = 10; //此行不同

*varp = 20;

編譯器會直接優化為:

int var = 5;

int *restrict varp = &var;

*varp = 20;//*varp = 10;編譯器不處理了。

gcc好像需要改變編譯器的優化等級(-o),才能實現上述功能。

關鍵字volatile和register

用關鍵字volatile宣告變數,是用來告訴編譯器每次對此變數的引用都需要從記憶體位址中讀取,即取消編譯器對此變數的優化編譯。當某次引用沒用volatile宣告的變數時,其被編譯器從記憶體位址中讀取到ax 某通用暫存器 中,那麼在其後的引用中,如果ax暫存器沒用被改變,那麼編譯器會優化成直接讀取ax...

關鍵字 mutable和volatile

1 mutable 在c 中,mutable是為了突破const的限制而設定的。被mutable修飾的變數,將永遠處於可變的狀態,即使在乙個const函式中,甚至結構體變數或者類物件為const,其mutable成員也可以被修改。1.structst 2.3.10.11.constst st 12....

關鍵字 volatile關鍵字的作用

1.volatile關鍵字是防止在共享的空間發生讀取的錯誤。只保證其可見性,不保證原子性 使用volatile指每次從記憶體中讀取資料,而不是從編譯器優化後的快取中讀取資料,簡單來講就是防止編譯器優化。2.在單任務環境中,如果在兩次讀取變數之間不改變變數的值,編譯器就會發生優化,會將ram中的值賦值...