一篇文章帶你了解C語言中volatile關(guān)鍵字
C語言中volatile關(guān)鍵字
volatile關(guān)鍵字是C語言中非常冷門的關(guān)鍵字,因?yàn)橛玫竭@個(gè)關(guān)鍵字的場(chǎng)景并不多。
當(dāng)不用這個(gè)關(guān)鍵字的時(shí)候,CPU可能會(huì)對(duì)我們的代碼做一定的優(yōu)化:
內(nèi)存中的數(shù)據(jù)要放入CPU中進(jìn)行運(yùn)算或控制,而這個(gè)數(shù)據(jù)的值是被放入寄存器中,然后再將寄存器中的數(shù)據(jù)進(jìn)行運(yùn)算或控制的,對(duì)于一個(gè)死循環(huán)int flag=1;while(flag);來說;如果進(jìn)行優(yōu)化,則下次循環(huán)則不需要再次將flag內(nèi)存中的值放入寄存器中,而是直接使用寄存器中已有的值進(jìn)行循環(huán);如果不進(jìn)行優(yōu)化,則下次還需要將flag內(nèi)存中的值放入寄存器中,然后使用寄存器中的數(shù)據(jù)。
總結(jié)起來就是,遇到這個(gè)關(guān)鍵字聲明的變量,編譯器對(duì)訪問該變量的代碼就不再進(jìn)行優(yōu)化,從而可以提供對(duì)其地址的穩(wěn)定訪問;如果不使用valatile,則編譯器將對(duì)所聲明的語句進(jìn)行優(yōu)化。
這兩種情況在單線程的情況下區(qū)別不大,但是在多線程的情況下可能會(huì)有其他邏輯將flag修改為0,如果進(jìn)行優(yōu)化,則死循環(huán)不會(huì)停下來。
所以volatile的作用就是讓變量不要被CPU優(yōu)化,達(dá)到穩(wěn)定訪問內(nèi)存的目的。
比如下面的代碼:

我們?cè)趃cc下使用命令gcc test.c -O2 -g將代碼進(jìn)行優(yōu)化,然后用命令objdump -S -d a.out > a.s將優(yōu)化后的匯編代碼放入a.s文件中,再用vim a.s查看a.s文件:

程序會(huì)一直在這一句代碼中死循環(huán):

加入volatile后:

再用相同的命令查看a.s文件:

可以看到每次循環(huán)都會(huì)讀取pass的數(shù)據(jù)。
結(jié)論: volatile 忽略編譯器的優(yōu)化,保持內(nèi)存可見性。
另外,const和volatile是不沖突的:
const volatile int a = 10;
const關(guān)鍵字要求變量a不能直接被寫入,而volatile關(guān)鍵字要求每次讀取數(shù)據(jù)的時(shí)候,都要從a所在的內(nèi)存中讀取,并不會(huì)改變變量a的值。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C++作用域與函數(shù)重載的實(shí)現(xiàn)
本文主要介紹了C++作用域與函數(shù)重載的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02
C++實(shí)現(xiàn)LeetCode(53.最大子數(shù)組)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(53.最大子數(shù)組),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07

