0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

關(guān)鍵字volatile是什么?volatile關(guān)鍵字對編譯器優(yōu)化的影響

Dp1040 ? 來源:strongerHuang ? 2023-11-03 11:47 ? 次閱讀

在我的技術(shù)交流群里,經(jīng)常會看到大家討論一些“奇怪”的問題,其中有好幾次我都發(fā)現(xiàn),是他們?nèi)肿兞俊叭堑牡湣?,問題就是全局變量被優(yōu)化導(dǎo)致的。

可能初學(xué)者不太關(guān)心編譯器優(yōu)化的功能,但對于經(jīng)驗豐富的工程師來說,掌握代碼優(yōu)化是必備技能。

今天,我們講述的話題就是關(guān)于代碼優(yōu)化中,關(guān)鍵字volatile在優(yōu)化過程中起到的作用。

關(guān)鍵字volatile是什么?

volatile是一個類型修飾符(type specifier)。

volatile的作用是作為指令關(guān)鍵字,確保本條指令不會因編譯器的優(yōu)化而省略,且要求每次直接讀值。

volatile變量是說這變量可能會被意想不到地改變,這樣,編譯器就不會去假設(shè)這個變量的值了。

---來自百度百科

volatile的定義,應(yīng)該在(讀書)學(xué)習(xí)時都看過無數(shù)遍,但我相信絕大部分人都沒有深刻理解其中含義

當(dāng)你真正編程、開發(fā)項目之后,你就會進(jìn)一步理解其中含義。

volatile關(guān)鍵字對編譯器優(yōu)化的影響

我們都知道編譯器有優(yōu)化代碼的功能,我們常用的集成開發(fā)環(huán)境(Keil、 IAR等)都有優(yōu)化選項。

473fd922-79e1-11ee-939d-92fbcf53809c.jpg

如果不使用關(guān)鍵字 volatile 申明變量,則編譯器可能會對變量的訪問并生成非預(yù)期的代碼或刪除預(yù)期的功能。

1、什么時候使用volatile?

常見使用volatile聲明的情況:

訪問內(nèi)存映射外設(shè)。

在多個線程之間共享全局變量。

在中斷例程或信號處理程序中訪問全局變量。

比如,在STM32代碼中:


#define __O volatile /*!< Defines 'write only' permissions */#define?????__IO????volatile?????????????/*!

瀏覽代碼,你會發(fā)現(xiàn),很多地方都使用了“__IO”,也就是volatile.

在跑系統(tǒng)的項目中,線程間共享的全局變量,建議都加上volatile關(guān)鍵字,這一點,很多人沒有在意。

2、不用volatile時可能出現(xiàn)的問題

如果未將變量用volatile聲明,則編譯器會假定其值不能在其定義的范圍之外進(jìn)行修改。

因此,編譯器可能會執(zhí)行不需要的優(yōu)化。這可以通過多種方式表現(xiàn)出來:

在輪詢硬件時,代碼可能會陷入循環(huán)。

多線程代碼可能會表現(xiàn)出奇怪的行為。

優(yōu)化可能會導(dǎo)致刪除實現(xiàn)故意時序延遲的代碼。

舉個例子,這是我自己寫一個延時函數(shù):


void Delay(int Cnt){ int i;

while(Cnt--) { i++; for(i=0; i<10; i++); ?}}

你在不同優(yōu)化等級情況下,延時時間可能會不一樣;

同樣的代碼,你在Keil 和 IAR環(huán)境下編譯出來的延時時間也可能不一樣。

當(dāng)然,更深入的理解就會牽涉到匯編代碼,編譯之后的匯編代碼會比較直觀的呈現(xiàn)差異。

本文轉(zhuǎn)載自strongerHuang

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1617

    瀏覽量

    49016
  • 關(guān)鍵字
    +關(guān)注

    關(guān)注

    0

    文章

    37

    瀏覽量

    6889
  • volatile
    +關(guān)注

    關(guān)注

    0

    文章

    44

    瀏覽量

    12997

原文標(biāo)題:全局變量加/不加volatile的影響

文章出處:【微信號:玩點嵌入式,微信公眾號:玩點嵌入式】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    C語言關(guān)鍵字--typedef

    C語言關(guān)鍵字使用方法學(xué)習(xí)指南!
    的頭像 發(fā)表于 10-07 12:44 ?153次閱讀

    使用邊緣AI和Sitara處理進(jìn)行關(guān)鍵字檢測

    電子發(fā)燒友網(wǎng)站提供《使用邊緣AI和Sitara處理進(jìn)行關(guān)鍵字檢測.pdf》資料免費(fèi)下載
    發(fā)表于 09-02 11:30 ?0次下載
    使用邊緣AI和Sitara處理<b class='flag-5'>器</b>進(jìn)行<b class='flag-5'>關(guān)鍵字</b>檢測

    快速掌握C語言關(guān)鍵字

    C語言中的32個關(guān)鍵字你知道多少個呢?根據(jù)關(guān)鍵字的作用分為四類:數(shù)據(jù)類型關(guān)鍵字、控制語句關(guān)鍵字、存儲類型關(guān)鍵字和其它
    的頭像 發(fā)表于 07-06 08:04 ?284次閱讀
    快速掌握C語言<b class='flag-5'>關(guān)鍵字</b>

    inline關(guān)鍵字優(yōu)化導(dǎo)致此類函數(shù)被布局在flash內(nèi),怎么處理?

    == 0));} 由于uart.c多處調(diào)用這個函數(shù),所以編譯器自作聰明地把它編譯成了非內(nèi)聯(lián)函數(shù)(意圖是減少代碼占用?),且elf能找到uart_ll_is_tx_idle標(biāo)號
    發(fā)表于 06-21 12:03

    IDF4.2.1的編譯器優(yōu)化bug導(dǎo)致panic怎么處理?

    == 0) && (status.st_utx_out == 0));} 它是一個inline函數(shù)。我們都認(rèn)為inline關(guān)鍵字,會告訴編譯器內(nèi)聯(lián)此函數(shù),于是它的代碼
    發(fā)表于 06-21 10:55

    簡單總結(jié)一下嵌入式C++中常見的錯誤形式

    對于 C++ 類,一些關(guān)鍵字只要寫在 .h 中就好,cpp 中就不用再加上了,比如 virtual、static 等關(guān)鍵字,如果在 cpp 中多寫,編譯器會報錯。
    的頭像 發(fā)表于 02-23 09:40 ?416次閱讀

    關(guān)鍵字搜索文件夾中某個TXT文件

    文件夾中隨時創(chuàng)造TXT文件,如何及時選出剛創(chuàng)造的文件?或關(guān)鍵字搜索出需要的TXT文件?
    發(fā)表于 02-06 15:22

    谷歌搜索引擎優(yōu)化的各個方面和步驟

    谷歌搜索引擎是最受歡迎和廣泛使用的搜索引擎之一,為了使你的網(wǎng)站在谷歌上更好地排名并提高曝光度,你可以采取一些谷歌搜索引擎優(yōu)化的步驟。 使用關(guān)鍵字研究工具,如Google AdWords關(guān)鍵字規(guī)劃工具
    的頭像 發(fā)表于 01-25 10:29 ?817次閱讀

    在NVM和本地\"內(nèi)存中定義數(shù)組(靜態(tài) /global /local)的\"關(guān)鍵字是什么?

    在 NVM 和本地\"內(nèi)存中定義數(shù)組(靜態(tài) /global /local)的\"關(guān)鍵字是什么? 還有與 32 位對齊的關(guān)鍵字怎么樣。
    發(fā)表于 01-25 07:52

    keil arm工程中結(jié)構(gòu)體1節(jié)對齊如何實現(xiàn)

    在Keil Arm工程中,結(jié)構(gòu)體的對齊方式可以通過使用特定的編譯器指令或者關(guān)鍵字來實現(xiàn)。結(jié)構(gòu)體的對齊方式會直接影響結(jié)構(gòu)體變量在內(nèi)存中的布局和對齊邊界,從而對程序的性能和存儲空間占用產(chǎn)生影響。 結(jié)構(gòu)體
    的頭像 發(fā)表于 01-05 14:40 ?3330次閱讀

    探討多線程編程中的volatile關(guān)鍵字應(yīng)用

    有時候,我們可能需要在指針類型之間進(jìn)行轉(zhuǎn)換,而編譯器會認(rèn)為這是不安全的操作,從而導(dǎo)致編譯錯誤。使用volatile關(guān)鍵字可以告知編譯器,這個
    發(fā)表于 12-27 13:53 ?399次閱讀

    你還記得這個C語言關(guān)鍵字嗎?

    當(dāng)你使用volatile關(guān)鍵字時,你告訴編譯器該變量的值可能會在程序的執(zhí)行過程中被外部因素更改,因此編譯器不應(yīng)該對該變量的讀寫進(jìn)行優(yōu)化。下面
    的頭像 發(fā)表于 12-17 08:00 ?325次閱讀
    你還記得這個C語言<b class='flag-5'>關(guān)鍵字</b>嗎?

    嵌入式軟件開發(fā)常用的關(guān)鍵字和運(yùn)算符

    volatile是一個特征修飾符,提醒編譯器它后面所定義的變量隨時都有可能改變,因此編譯后的程序每次需要存儲或讀取這個變量的時候,告訴編譯器對該變量不做
    的頭像 發(fā)表于 12-04 12:22 ?549次閱讀

    vlookup提取關(guān)鍵字匹配多個結(jié)果

    是它能夠基于關(guān)鍵字匹配提取多個結(jié)果。 當(dāng)使用VLOOKUP提取多個結(jié)果時,需要遵循以下幾個重要步驟。首先,您需要確保數(shù)據(jù)的組織和結(jié)構(gòu)正確。數(shù)據(jù)應(yīng)以表格格式排列,左側(cè)為關(guān)鍵字列,右側(cè)為相應(yīng)的信息列。 首先,讓我們考慮一個實際的例子。假設(shè)您有一個大型數(shù)據(jù)集
    的頭像 發(fā)表于 12-01 10:40 ?2283次閱讀

    編譯器通常會怎么去處理使用volatile修飾的變量呢?

    在嵌入式軟件開發(fā)過程中,如果對volatile不熟,那可以你應(yīng)該是個"假嵌入式程序員",因為一個變量需不需要使用volatile考慮的場景挺多的
    的頭像 發(fā)表于 11-29 10:05 ?340次閱讀
    <b class='flag-5'>編譯器</b>通常會怎么去處理使用<b class='flag-5'>volatile</b>修飾的變量呢?