Sabit ve Sabit Uçucu Arasındaki Fark


90

Bir değişkeni volatileher yeni değer güncellendiğinde
ilan edersek Bir değişkeni olduğu gibi ilan edersek consto değişkenin değeri değişmez

O const volatile int temp;
halde değişkeni tempyukarıdaki gibi bildirmenin faydası nedir ?
Olarak ilan edersek ne olur const int temp?


Sen kullanmak ister const volatile int temp;blok kapsamı (yani iç de { }o hiçbir faydası yoktur vardır).
MM

Yanıtlar:


149

Olarak işaretlenmiş bir nesnenin const volatilekod tarafından değiştirilmesine izin verilmez ( constniteleyici nedeniyle bir hata ortaya çıkar ) - en azından o belirli ad / işaretçi aracılığıyla.

Niteleyicinin volatileparçası, derleyicinin nesneye erişimi optimize edemeyeceği veya yeniden sıralayamayacağı anlamına gelir.

Gömülü bir sistemde, bu genellikle donanım tarafından okunabilen ve güncelleştirilen, ancak yazmanın bir anlamı olmayan (veya yazılması gereken bir hata olabilir) donanım kayıtlarına erişmek için kullanılır.

Bir seri bağlantı noktasının durum kaydı bir örnek olabilir. Çeşitli bitler, bir karakterin okunmayı beklediğini veya aktarım kaydının yeni bir karakteri kabul etmeye hazır olup olmadığını (yani, - boş) gösterir. Bu durum yazmacının her okunması, seri port donanımında başka neler olduğuna bağlı olarak farklı bir değerle sonuçlanabilir.

Durum yazmacına yazmanın bir anlamı yoktur (belirli donanım özelliklerine bağlı olarak), ancak her bir yazmaç okumasının, donanımın gerçek bir okumasıyla sonuçlandığından emin olmanız gerekir - önceki bir okuma kazanımından önbelleğe alınmış bir değer kullanarak '' size donanım durumundaki değişikliklerden bahsetmiyorum.

Hızlı bir örnek:

Bu işaretçiler var olarak işaretlenmemişse volatilebirkaç sorun ortaya çıkabilir:

  • while döngüsü testi, durum kaydını yalnızca bir kez okuyabilir, çünkü derleyici işaret ettiği şeyin asla değişmeyeceğini varsayabilir (while döngüsü testinde veya döngüsünde onu değiştirebilecek hiçbir şey yoktur). İşleve UART donanımında bekleyen karakter yokken girdiyseniz, bir karakter alındığında bile hiç durmayan sonsuz bir döngü ile karşılaşabilirsiniz.
  • alma yazmacının okunması derleyici tarafından while döngüsünden önceye taşınabilir - yine işlevde *recv_regdöngü tarafından değiştirildiğini gösteren hiçbir şey olmadığından, döngüye girmeden önce okunamamasının bir nedeni yoktur.

volatileEleme olmasını sağlar bu optimizasyonlar derleyici tarafından gerçekleştirilen olmadığını.


5
Açıklama için +1. Ve bir sorum var: const uçucu yöntemler ne olacak? Birçok iş parçacığı tarafından erişilen bir sınıfa sahipsem (erişim mutex ile senkronize olsa da), const yöntemlerim de geçici olmak zorunda mıdır (çünkü bazı değişkenler başka bir iş parçacığı tarafından değiştirilebilir)
Sasa

41
  • volatile derleyiciye değişkenle ilgili kodu optimize etmemesini söyleyecektir, genellikle onun "dışarıdan" değiştirilebileceğini bildiğimizde, örneğin başka bir evre ile.
  • const derleyiciye programın değişkenin değerini değiştirmesinin yasak olduğunu söyleyecektir.
  • const volatilemuhtemelen hayatınızda tam olarak 0 kez kullanıldığını göreceğiniz çok özel bir şey (tm). Bekleneceği gibi bu, programın değişkenin değerini değiştiremeyeceği, ancak değerin dışarıdan değiştirilebileceği, dolayısıyla değişken üzerinde optimizasyon yapılmayacağı anlamına gelir.

12
volatileDeğişkenlerin genellikle diğer konularla değil, donanımla uğraşmaya başladığınızda olan şey olduğunu düşünmüştüm . const volatileKullanıldığını gördüğüm yer , bellek eşlemeli durum kayıtları veya benzeri şeylerdir.
SADECE DOĞRU GÖRÜŞÜM

2
Tabii ki, kesinlikle haklısınız, çoklu okuma sadece bir örnek, ancak tek örnek değil :).
mingos

26
Gömülü sistemlerle çalışıyorsanız, bunu çok sık göreceksiniz.
Daniel Grillo

29

Değişkenin sabit olması nedeniyle iki sıra noktası arasında değişmemiş olabilir.

Sabitlik, değeri değiştirmeyeceğinize dair bir sözdür, değerin değiştirilmeyeceği anlamına gelmez.


10
Artı, constverilerin "sabit" olmadığını belirtmek için .
Bogdan Alexandru

7

Bunu, bazı yapılandırma değişkenlerinin bir önyükleyici tarafından güncellenebilen bir flash bellek alanında bulunduğu yerleşik bir uygulamada kullanmam gerekiyordu. Bu yapılandırma değişkenleri çalışma süresi boyunca 'sabittir', ancak geçici niteleyici olmadan derleyici bunun gibi bir şeyi optimize eder ...

... sabit değeri önceden hesaplayarak ve anında bir montaj talimatı kullanarak veya sabiti yakındaki bir yerden yükleyerek, böylece yapılandırma flaş alanındaki orijinal CANID değerine yönelik herhangi bir güncelleme göz ardı edilir. CANID sabit değişken olmalıdır.


7

C'de constve volatiletür niteleyicilerdir ve bu ikisi bağımsızdır.

Temel olarak, constdeğerin program tarafından değiştirilemeyeceği anlamına gelir.

Ve volatiledeğerin ani bir değişikliğe tabi olduğu anlamına gelir (muhtemelen programın dışından).

Aslında, C Standardı hem constve hem de olan geçerli bir beyana örnek verir volatile. Örnek şudur:

extern const volatile int real_time_clock;

burada real_time_clockdonanım tarafından değiştirilebilir, ancak atanamaz, artırılamaz veya azaltılamaz.

Biz zaten davranmalı Yani constve volatileayrı ayrı. Bu tip kalifiye uygulanabilir struct, union, enumve typedefhem de.


5

constdeğişkenin c kodu ile değiştirilemeyeceği, değiştirilemeyeceği anlamına gelir. Bu, hiçbir talimatın değişkene yazamayacağı, ancak değerinin yine de değişebileceği anlamına gelir.

volatiledeğişkenin herhangi bir zamanda değişebileceği ve dolayısıyla önbelleğe alınan hiçbir değerin kullanılamayacağı anlamına gelir; değişkene her erişim, hafıza adresine yürütülmelidir.

Soru "gömülü" olarak etiketlendiğinden ve tempdonanımla ilgili bir kayıt değil, kullanıcı tarafından tanımlanan bir değişken olduğu için (bunlar genellikle ayrı bir .h dosyasında ele alındıklarından), şunları göz önünde bulundurun:

Hem geçici okuma-yazma veri belleğine (RAM) hem de geçici olmayan salt okunur veri belleğine sahip gömülü bir işlemci, örneğin veri ve program alanının ortak bir veri ve adres yolunu paylaştığı von-Neumann mimarisinde FLASH bellek.

const tempBir değere sahip olduğunuzu beyan ederseniz (en azından 0'dan farklıysa), derleyici değişkeni FLASH alanındaki bir adrese atayacaktır, çünkü bir RAM adresine atanmış olsa bile, başlangıç ​​değerini saklamak için yine de FLASH belleğe ihtiyaç duyar. Tüm işlemler salt okunur olduğundan RAM adresini alan israfı haline getirir.

Sonuç olarak:

int temp;RAM'de depolanan bir değişkendir, başlangıçta 0 olarak başlatılır (cstart), önbelleğe alınan değerler kullanılabilir.

const int temp;FLASH'da depolanan bir değişkendir, derleyici zamanında 0 olarak başlatılır, önbelleğe alınan değerler kullanılabilir.

volatile int temp; RAM'de saklanan bir değişkendir, başlangıçta 0 olarak başlatılır (cstart), önbelleğe alınan değerler KULLANILMAZ.

const volatile int temp; FLASH'da depolanan bir değişkendir, derleyici zamanında 0 olarak başlatılır, önbelleğe alınan değerler KULLANILMAZ

İşte yararlı kısım:

Günümüzde Gömülü işlemcilerin çoğu, özel bir işlev modülü aracılığıyla salt okunur geçici olmayan belleklerinde değişiklik yapma olanağına sahiptir, bu durumda const int tempdoğrudan olmasa da çalışma zamanında değiştirilebilir. Başka bir şekilde söylenirse, bir fonksiyon tempsaklandığı adresteki değeri değiştirebilir .

Pratik bir örnek temp, cihazın seri numarası için kullanmak olacaktır . İlk kez gömülü işlemci çalışır, temp0'a eşit (ya da beyan edilen değer) olacak ve bir fonksiyonu, bir seri numarası tahsis edilmesi için, üretim sırasında ve başarılı sayılabilmek eğer bir test için, bu gerçeği sormak kullanımı ve değerini değiştirmek için tempvasıtasıyla özel bir işlev. Bazı işlemcilerin sadece bunun için OTP (tek seferlik programlanabilir) belleğe sahip özel bir adres aralığı vardır.

Ama işte fark geliyor:

Bir const int tempdefalık programlanabilir seri numarası yerine değiştirilebilir bir kimlik ise ve bildirilmemişse volatile, bir sonraki önyüklemeye kadar önbelleğe alınmış bir değer kullanılabilir, yani yeni kimlik bir sonraki yeniden başlatmaya veya daha da kötüsü bazı işlevlere kadar geçerli olmayabilir. yeni değeri kullanabilirken, diğeri yeniden başlatılıncaya kadar daha eski bir önbelleğe alınmış değeri kullanabilir. const int tempIS beyan edilirse voltaile, kimlik değişikliği hemen geçerli olacaktır.


Wow bu cevap uzun

5

constVe volatilebirlikte kullanabilirsiniz . Örneğin, 0x30yalnızca dış koşullar tarafından değiştirilen bir bağlantı noktasının değeri olduğu varsayılırsa, aşağıdaki açıklama herhangi bir kaza sonucu yan etki olasılığını önleyecektir:



2

Basit bir ifadeyle, 'const volatile' değişkenindeki değer, program aracılığıyla değiştirilemez, ancak donanım tarafından değiştirilebilir. Burada uçucu, herhangi bir derleyici optimizasyonunu önlemektir.


1

Programın onu değiştirmesini istemediğimizde bir değişken için 'const' anahtar sözcüğünü kullanırız. Oysa bir değişken 'sabit uçucu' olarak tanımladığımızda, programa ve derleyiciye bu değişkenin dış dünyadan gelen girdilerden beklenmedik bir şekilde değiştirilebileceğini söylüyoruz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.