C ++ 'da uçucu ve değişken


86

Uçucu ve değişken arasındaki fark hakkında bir sorum var. Her ikisinin de değiştirilebileceği anlamına geldiğini fark ettim. Başka? Aynı şey mi? Fark ne? Nerelerde uygulanabilir? Neden iki fikir öneriliyor? Bunları farklı bir şekilde nasıl kullanırız?

Çok teşekkürler.

Yanıtlar:


113

Bir işaretçi veya referans mutablearacılığıyla erişilen bir nesnede constveya bir nesnede bile bir alan değiştirilebilir const, böylece derleyici onu R / O belleğinde saklamaması gerektiğini bilir. volatileKonum, derleyicinin bilmediği kodla değiştirilebilen bir konumdur (örneğin, bazı çekirdek düzeyinde sürücüler), bu nedenle derleyici, örneğin, "değerinin sahip olamayacağı" geçersiz varsayımı altında bu değerin kayıt atamasını optimize etmemeyi bilir. o kayıt defterine son yüklendiği için "değişti. Çok farklı türde geçersiz optimizasyonları durdurmak için derleyiciye çok farklı türde bilgiler veriliyor.


13
volatilenesneler, CPU'yu hiç içermeyen süreçler tarafından da değiştirilebilir. Örneğin, bir iletişim çevre biriminde bayt tarafından alınan bir kayıt, bir bayt alındığında kendisini artırabilir (ve bu, bir kesmeyi bile tetikleyebilir). Başka bir örnek, bir çevre birimdeki bekleyen-kesinti bayrakları kaydıdır.
Mike DeSimone

56
Ayrıca, volatileyalnızca nesnenin derleyicinin bilgisi dışında değişebileceği anlamına gelmez - aynı zamanda nesneye yazmanın, bu yazılar işe yaramaz görünse bile derleyici tarafından ortadan kaldırılamayacağı anlamına gelir. Örneğin: x = 1; x = 0; Eğer xuçucu derleyici (donanım seviyesinde anlamlı olabilir) her iki yazma işlemleri göndermek zorundadır. Ancak, uçucu olmayan bir nesne için, derleyici 1hiç kullanılmadığı için yazmakla uğraşmamayı seçebilir .
Michael Burr

15
Bir nesne hem constve hem de volatile! Nesneyi değiştiremezsiniz, ancak arkanızdan değiştirilebilir.
CTMacUser

2
@Destructor: Olağan durum, bir donanım aygıt kaydına yazmalar içindir.
Michael Burr

5
@Destructor bir LED'in durumunu kontrol ettiğinizi varsayalım. Yazma 0 onu KAPATIR, 1 yazın AÇAR. Bazı hata durumlarını bildirmek için LED'i yakmam gerekirse, ancak derleyici, değerlerin hiçbiri kullanılmadığından sonuncusu dışındaki tüm yazma işlemlerini optimize etmeye karar verirse, LED asla yanıp sönmez ve istediğim davranış gerçekleşmez .
iheanyi

28

mutable: Mutable anahtar sözcüğü, çevreleyen tüm const ifadelerini geçersiz kılar. Bir const nesnesinin değiştirilebilir bir üyesi değiştirilebilir.

volatile: Volatile anahtar sözcüğü, değişkenleri bildirirken kullanılan ve derleyicinin bu değişkenleri optimize etmesini engelleyen uygulamaya bağlı bir değiştiricidir. Uçucu, değeri beklenmedik şekillerde (yani bir kesme yoluyla) değişebilen, derleyicinin gerçekleştirebileceği optimizasyonlarla çelişebilecek değişkenlerle kullanılmalıdır.

Kaynak


Volatile should be used with variables whose value can change in unexpected waysrastgele kullanmayı tercih etmeli miyiz dedin ?
Asif Mushtaq

@AsifMushtaq değerler değil. yollar. değiştirilebilir, yazdığınız kodun sahip olduğu izinleri etkiler. Böylece değişkene const ptr veya const referansı aracılığıyla erişebilirsiniz. Ya sizin kodunuz onu değiştirmiyorsa? Derleyicinin ptr'yi veya başvuru türünü kontrol edemediği bir şey? Bu uçucu. Uçucu ayrıca önbelleği ana belleğe geri yazmaya zorlar. Dolayısıyla bu, çok iş parçacıklı kodlu bir LOT kullanılır. :)
Dan

22

Kesinlikle aynı şey DEĞİLDİR. Değişken, const ile etkileşime girer. Bir const işaretçiniz varsa, normalde üyeleri değiştiremezsiniz. Değişken, bu kurala bir istisna sağlar.

Öte yandan uçucu, program tarafından yapılan değişikliklerle tamamen ilgisizdir. Bu, belleğin derleyicinin kontrolü dışındaki nedenlerle değişebileceği anlamına gelir, bu nedenle derleyicinin her seferinde bellek adresini okuması veya yazması gerekir ve içeriği bir kayıt defterinde önbelleğe alamaz.


"Öte yandan uçucu, program tarafından yapılan değişikliklerle tamamen ilgisizdir ..." - hmmm, bir üyeyi uçucu hale getirin ve derleme sırasında hangi kesintileri görün. Bundan sonra uçucu eklemeye çalışmak, gerçeğin ardından const eklemeye çalışmak gibidir ... Ağrılı.
jww

@jww: Program tarafından yapılan yazılar ile hiçbir ilgisi yok. Bir tür nesnenin adresini alabilir Tve bunu a içine kaydedebilir ve ondan const T*okuyabilirsiniz. Bu nesneyi yaparsanız, asla yazmaya çalışmasanız bile volatileadresini saklamak const T*başarısız olur. volatileve program kodundan yapılan değişiklikler / modifikasyonlar / bellek yazıları tamamen ortogonaldir.
Ben Voigt

17

Farklılığın kaba ama etkili bir düşünme yolu şudur:

  • Derleyici, değiştirilebilir bir nesnenin ne zaman değiştiğini bilir.
  • Derleyici, uçucu bir nesnenin ne zaman değiştiğini bilemez.

1
Bu şekilde: volatilebytes_received, mutablereference_count.
Mike DeSimone

11

İşaretli bir değişken mutable, açıklanan bir yöntemde değiştirilmesine izin verir const.

İşaretli bir değişken volatile, derleyiciye, kodunuz ona her söylediğinde değişkeni okuması / yazması gerektiğini söyler (yani, değişkene erişimi optimize edemez).


4

Eklemek isterim ki, uçucu çok iş parçacıklı uygulamalarla uğraşırken çok yararlıdır, yani ana iş parçacığına sahipsiniz (main () yaşadığı yerde) ve bir değişken "app_running" doğruyken dönmeye devam edecek bir çalışan iş parçacığı oluşturursunuz. main (), "app_running" öğesinin doğru mu yanlış mı olduğunu kontrol eder, bu nedenle "app_running" bildirimine volatile niteliğini eklemezseniz, derleyici ikincil evre tarafından çalıştırılan koddaki "app_running" öğesine erişimi optimize ederse main ( ) "app_running" değerini yanlış olarak değiştirebilir, ancak ikincil iş parçacığı, değer önbelleğe alındığı için çalışmaya devam edecektir. Linux ve VisualC ++ üzerinde gcc kullanırken aynı davranışı gördüm. "App_running" bildirimine eklenen "uçucu" bir özellik sorunu çözdü. Yani,


1
Hayır! Bu yaygın bir yanlış anlaşılmadır. C ++ 11 ve C11, bu amaç için atomları tanıttı stackoverflow.com/questions/8819095/…
KristianR
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.