C語言中volatile關鍵字的使用

2021-01-13 電子發燒友
打開APP
C語言中volatile關鍵字的使用

發表於 2018-03-17 11:55:00

volatile的意思是易變的、可變的,作用是限制編譯器優化某些變量。首先看一段C51程序:

Keil在優化級別是為8時得到如下彙編代碼(部分未列出):

可以看到,變量d的值賦給x,y,z時,只有x中是直接讀取的d中數值,而y=d,z=d則直接將寄存器中的數值賦給y,z。若在此過程中,變量d的值被改變(比如d是一個硬體寄存器),則y,z變量中得到的數據將是錯誤的,因此在某些應用中程序存在隱患。

這類問題並不是編譯器的問題。由於訪問內部寄存器比訪問RAM速度塊,因此編譯器在編譯類似程序時,會對程序進行優化,除第一次編譯變量所在在連續讀取一個變量時,編譯器為了簡化程序,只要有可能就會把第一次讀取的值放在ACC或Rx中,在以後的讀取該變量的值時就直接使用第一次的讀取值。如果該變量的值在此過程中已經被外設(如讀取外部設備埠時經常將外設埠看作一外部RAM地址)或其他程序(如中斷服務程序)所改變,可能就會出錯。為了解決這類問題,常用的方法就是降低編譯器的優化級別或者使用volatile關鍵字。顯然降低優化級別不是所期望的,因此用volatile關鍵字修飾相關變量很有必要。

上文中的例子將d加上volatile關鍵字後,如下:

重新編譯得到的代碼(部分未列出)如下:

可以看這此y,z變量的值是從d的存儲區中讀取的。這主要是由編譯器的優化早成的,而不是編譯器的錯誤。用volatile變量對變量d修飾後,編譯器不對這個變量的操作進行優化,代碼的執行達到期望的目的。

一般說來,volatile關鍵字用在如下的幾個地方。

(1)中斷服務程序中修改的供其他程序檢測的變量需要加volatile。

(2)多任務環境下各任務間共享的標誌應該加volatile。

(3)存儲器映射的硬體寄存器通常也要加volatile說明,因為每次對它的讀寫都可能有不同意義。

打開APP閱讀更多精彩內容

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容圖片侵權或者其他問題,請聯繫本站作侵刪。 侵權投訴

相關焦點

  • C語言 關鍵字(32+5+7)
    月16日,ISO推出了C99標準,該標準新增了5個C語言關鍵字:inline restrict _Bool _Complex _Imaginary2011年12月8日,ISO發布C語言的新標準C11,該標準新增了7個C語言關鍵字:_Alignas _Alignof _Atomic _Static_assert _Noreturn _Thread_local
  • DSP編程技巧之17---非常「關鍵」的關鍵字
    什麼是「關鍵字」?關鍵字就是已被C語言本身使用,不能作其它用途使用的字,例如關鍵字不能用作變量名、函數名等。那「關鍵字」到底有多關鍵?簡單得說,就是如果不掌握它們的使用方法,程序就不能按照我們的設計產生預期的結果。
  • C/C++中常用的編程關鍵字
    關鍵字作用:關鍵字是C++中預先保留的單詞(標識符)在定義變量或者常量時候,不要用關鍵字C++關鍵字如下:20. export為了訪問其他編譯單元(如另一代碼文件)中的變量或對象,對普通類型(包括基本數據類、結構和類),可以利用關鍵字 extern,來使用這些變量或對象時;但是對模板類型,則必須在定義這些模板類對象和模板函數時,使用標準 C++ 新增加的關鍵字 export(導出)。
  • C語言宏定義#define的理解與資料整理
    看例子:#define PI 3.141592654在此後的代碼中你盡可以使用PI 來代替3.141592654,而且你最好就這麼做。不然的話,如果我要把PI 的精度再提高一些,你是否願意一個一個的去修改這串數呢?你能保證不漏不出錯?而使用PI 的話,我們卻只需要修改一次(這是十分高效的)。
  • 26張圖帶你徹底搞懂volatile關鍵字
    小牛說:...問的volatile關鍵字。小艾說:volatile關鍵詞的作用一般有如下兩個:可見性:當一個線程修改了由volatile關鍵字修飾的變量的值時,其它線程能夠立即得知這個修改。有序性:禁止編譯器關於操作volatile關鍵詞修飾的變量的指令重排序。
  • C/C+編程筆記:C語言編程面試常見問題,全是經典題!
    C語言的主要特徵是什麼? C是一種過程語言。 4)在C ++中,++ i可用作左值,但i ++不能用作左值。在C中,它們都不能用作l值。 什麼是l值? l值或位置值是指可以在賦值運算符左側使用的表達式。例如,在表達式「 a = 3」中,a是l值,而3是r值。
  • C語言中const關鍵字的妙用總結
    請看正文學習了多年的C語言,你對const關鍵字的使用全都掌握了嗎?在編程實踐中你對const的使用是否有困惑呢?今天就給大家一起來探討總結,期望能夠大家解惑並提供參考。C語言中const關鍵字是constant的縮寫,通常翻譯為常量、常數等,有些朋友一看到const關鍵字馬上就想到了常量。事實上在C語言中const功能很強大,它可以修飾變量、數組、指針、函數參數等。本文將針對上述幾種修飾功能詳細做一個總結。
  • CPU有緩存一致性協議MESI,為何還需要Volatile?
    前面我們從作業系統底層了解了現代計算機結構模型中的CPU指令結構、CPU緩存結構、CPU運行調度以及作業系統內存管理,並且學習了Java內存模型(JMM)和 volatile 關鍵字的一些特性。本篇來深入理解CPU緩存一致性協議(MESI),最後來討論既然CPU有緩存一致性協議(MESI),為什麼JMM還需要volatile關鍵字?
  • 一步帶您了解C語言中的「register」關鍵字
    寄存器比內存訪問要快,因此可以使用register關鍵字將C程序中最常用的變量放入寄存器中。關鍵字register會向編譯器提示可以將給定變量放入寄存器中。編譯器可以選擇是否將其保存在寄存器中。通常,編譯器自己進行優化,然後將變量放入寄存器中。
  • 快速上手系列-C語言之基礎篇(一)
    若干個庫文件:庫文件是編譯後的二進位文件,一般由若干C文件編譯後組成,其中包含了若干個函數的可執行代碼;這些庫文件中的函數可執行代碼在連接的時候合併到最終的可執行文件中。若干個make文件:make文件描述了多個文件中的依賴關係以及生成最終可執行文件或庫文件所需要的信息。由於篇幅較小,再加點內容,順便寫寫C語言的關鍵字和控制語句。
  • C/C+編程筆記:在C+中如何調用C語言的代碼?你可以這樣做
    比如在C文件中存在一個函數func_c(), 該文件與C++的工程混編在一起時,可以直接在C++中調用C文件中的func_c();不需要做任何額外處理。 而在C語言中是沒有這個技術的,所以如果我們想要調用C語言開發的一些API,就需要使用 extern "C"修飾C語言的函數聲明。
  • C語言關鍵字 -(typedef關鍵字)
    這就是那隻小烏龜typedef關鍵字就是擅長做障眼法,任何其他類型遇上他就可以變身成其他的模樣,這麼厲害的關鍵字,我們可一定要供著,因為實在太牛了。(storage class specifier)這種說法是不是有點令人驚訝,typedef 就像 auto,extern,mutable,static,和 register 一樣,是一個存儲類關鍵字。
  • C語言中的變量存儲類型static老手都這樣用
    具體變量介紹請見作者的另一篇文章,名為《說一說C語言中的變量存儲類型——「extern」》。下面我們直接講乾貨,static關鍵字用法。2、 Static關鍵字用法C語言中,無論是變量還是函數都可以用static關鍵字來修飾。具體用法我們分別來看。
  • 單片機C語言模塊化編程方法
    .h文件中給出模塊的接口.在上面的例子中,向LCD寫入字符函數:wr_lcd (uchar dat_comm,uchar content)就是一個接口函數,因為其它模塊會調用它,那麼.h文件中就必須將這個函數聲明為外部函數(使用extrun關鍵字修飾),另一個延時函數:void delay (uint us)只是在本模塊中使用(本地函數,用static關鍵字修飾),因此它是不需要放到
  • 淺析Java中的final關鍵字
    談到final關鍵字,想必很多人都不陌生,在使用匿名內部類的時候可能會經常用到final關鍵字。另外,Java中的String類就是一個final類,那麼今天我們就來了解final這個關鍵字的用法。下面是本文的目錄大綱:  一.final關鍵字的基本用法  二.深入理解final關鍵字  若有不正之處,請多多諒解並歡迎指正。
  • goto關鍵字你不知道的"那些事"(C語言提升)
    好了,要進入今天的主題了,今天我們要討論的是C語言中相對比較冷門的知識關鍵字goto!    關鍵字goto從字面的意思就是"去哪裡"的意思,專業一點的話表示無條件跳轉的意思(有學過彙編的小夥伴應該會覺得非常像jump指令),在C語言中的使用格式是:goto label,表示跳轉到label的位置,並且我們的label一般都寫在語句的開頭,寫成label:的形式。
  • C語言數據類型本質分析
    1、數據類型概念:類型是對數據的抽象,類型相同的數據在內存中有同樣的存儲格式、表現形式。在一段程序中,所用到的數據一定屬於某一個類型。
  • C++中的指針與引用
    const-volatile限定符)。const類對象的非靜態、非mutable、以及非引用數據成員是const-qualified;volatile類對象的非靜態、非引用數據成員是volatile-qualified;const-volatile類對象的非靜態、非引用數據成員是const-volatile-qualified。
  • C語言基礎(下)
    C語言的世界結構體類型什麼是結構體我們觀察現實世界的時候,可以發現很多的東西它都是由不同的部分組合起來的s\n", stu.gender); printf("%s\n", stu.mail); printf("%d\n", stu.age);結構體數組語法定義struct Student{char * name;}stu[5];使用上與單個結構體變量相同,在數組中需要加上在數組中的下標
  • 「C語言指針」起別名關鍵字typedef和結構體類型的恩怨情仇
    在上一篇文章中,我們簡要了解了鍊表的前導知識——結構體和它的眾多小細節。其中提到了起別名關鍵字typedef,在那裡我們只是簡單介紹過:在實際工作中,程式設計師們普遍使用它,但是並未展開去講細節。首先,typedef是C語言的一個關鍵字,它的作用是為類型名定義別名。