Uçucu bir değişken bildirmek ne demektir?


9

Birçok düşük seviyeli program, bellek eşleme ve benzeri türler için uçucu anahtar kelimeyi kullanır, ancak GERÇEKTEN arka planda ne yaptığı konusunda biraz kafam karıştı . Başka bir deyişle, derleyici bellek adresini "optimize etmediğinde" ne anlama gelir?


1
Yaşınızı bir volatiledeğişkenten okuyorsanız ve 5 diyorsa ve gelecek yıl tekrar okursanız, 6 elde edersiniz.
5gon12eder

@ 5gon12eder, uçucu bir şeyin hızlı ve kolay değişime tabi olduğu anlamına geldiğini anlıyorum, ama bu nasıl çalışıyor? : S
Vikaton

Ayrıca, derleme bayraklarınıza bağlı olarak, hata ayıklayıcınızda kalıcı olmayan bir değişken 'olabilir' görünebilir (örneğin C kodu + Eclipse + gdb kullandığınızı varsayalım), örneğin: 'optimize edilmiş değer' çünkü değişkenin değeri artık bir yerde bir sicilde. Montaj dili hata ayıklama araçlarını / özelliklerini nasıl kullanacağınızı bilmiyorsanız, değişkeninizi değişken değişken kullanarak bildirin.

Yanıtlar:


11

volatile başka bir işlemci veya G / Ç aygıtı veya başka bir şey değişkenin altınızdan değiştirilebileceği anlamına gelir.

Sıradan bir değişkenle, programınızın adımları onu değiştirecek tek şeydir. Örneğin 5, bir değişkenden okuduysanız ve değiştirmezseniz, yine de içerecektir 5. Buna güvenebileceğinizden, programınızın değişkeni bir daha kullanmak istediğinizde tekrar okumak için zaman alması gerekmez. C ++ derleyicisi sadece hatırlar kod üretmek akıllı 5.

Ama bunu şöyle okuyabilirsiniz 5, o zaman belki sistem verileri diskten o belleğe yükler ve olarak değiştirir 500. Programınızın yeni değeri okumasını 500istiyorsanız, derleyicinin önceden okunan kullanımı konusunda fazla akıllı olmaması gerekir 5. Her seferinde değeri yeniden yüklemesini söylemeniz gerekir. İşte volatileböyle.

5 yaşındakiler için bir benzetme
Masaya büyük bir sayfa koyduğunuzu varsayalım. Kağıdın bir köşesinde devam etmekte olan bir oyunun şu anki puanını yazıyorsunuz 3 to 4. Sonra masanın karşı tarafına gidin ve oyun hakkında bir hikaye yazmaya başlayın. Oyunu izleyen arkadaşınız, oyun ilerledikçe o köşedeki puanı günceller. Siler 3 to 4ve yazar 3 to 5.

Oyun skorunu hikayenize koyduğunuzda, aşağıdakilerden birini yapabilirsiniz:

  1. Okuduğunuz son puanı yazın 3 to 4, neyse ki değişmediğini varsayarak (veya değiştiyse sakıncası yoksa) veya
  2. Geçerli puanı okumak için tablonun karşı tarafına doğru yürüyün ( 3 to 5şimdi olur ) ve geriye doğru yürüyün. Bir volatiledeğişken böyle davranır.

11

volatile iki anlama gelir:

  1. Değişkenin değeri, herhangi bir kodu değiştirmeden değişebilir. Derleyici değişkenin değerini okur nedenle açıldığında işlem olabilir değil buna okundu son kez aynıdır, ya da depolanan son değer olarak aynıdır, ancak yine okumak gerektiğini varsayalım.

  2. Bir değeri değişken bir değişkene saklama eylemi dışarıdan gözlemlenebilen bir "yan etki" dir, bu nedenle derleyicinin bir değeri saklama eylemini kaldırmasına izin verilmez; örneğin, bir satırda iki değer depolanıyorsa, derleyicinin aslında değeri iki kez depolaması gerekir.

Örnek olarak:

i = 2; 
i = i; 

Derleyici gerekir , değişken okuduğum, iki numara saklamak o i içine okumanız değişkeni saklayın.

Başka bir durum daha vardır: Bir işlev kullanır setjmpve sonra longjmpçağrılırsa, işlevin tüm değişken yerel değişkenlerinin son değerin depolandığı garanti edilir - bu, geçici olmayan yerel değişkenler için geçerli değildir.


Burada bazı ince sorunlar var. İnce bir sorun, değişken değişkenlerin aslında değişkene nasıl erişildiğinin bir özelliği olması durumunda değişkenin bir özelliği olarak karakterize etmenizdir . Değişkeni ive değeri varsa pi = &i, o x = *pizaman bir okuma yapar i, ancak bu okumanın değişken anlambilimine sahip olduğu garanti edilmez.
Eric Lippert

1
@EricLippert: Eğer iolarak ilan edilir volatile int idaha sonra piilan edilmelidir volatile int *piki bu durumda, *pihayır, uçucu bir erişim nedir?
Jon Purdy

2

Özet açıklama
Hem C hem de C ++ soyut bir makine kavramına sahiptir . Kod bazı değişkenlerin değerini kullandığında, soyut makine uygulamanın bu değişkenin değerine erişmesi gerektiğini söyler. Formun kodu statement_A; statement_B; statement_C;tam olarak belirtilen sırada yürütülmelidir. Bu üç ifadede ortak olan ifadeler, her gerçekleştiklerinde yeniden hesaplanmalıdır.

Bildiri dizisi göz önüne alındığında, soyut makinelere göre, statement_A; statement_B; statement_C;uygulama ilk önce statement_Abütünüyle, daha sonra statement_Bve sonunda gerçekleştirilmelidir statement_C. Uygulama, age5 değerini atadığınızı hatırlayamıyor . Referans veren her ifade bunun ageyerine bu değişkenin değerine erişmelidir.

volatileUygulamalar soyut makine spesifikasyonlarına göre kesinlikle C veya C ++ kodu çalıştırıldıysa anahtar kelimeye gerek yoktur . C ve C ++ soyut makinelerinin kayıt kavramı, ortak alt ifadeler kavramı yoktur ve yürütme sırası katıdır.

Her iki dilde de if kuralları vardır. Bir uygulama, soyut makine şartnamesine göre bir şeyler yürütmüş gibi davrandığı sürece standartla uyumludur . Derleyici, değişken olmayan değişkenlerin atamalar arasındaki değerleri değiştirmediğini varsayabilir. Yani sürece kesilmez olarak as-ifkural, dizi statement_A; statement_B; statement_C;parçasını yürüterek uygulanabileceği statement_Csonra parçası, statement_Adaha sonra Herşeyden statement_B, daha sonra kalanını statement_Ave son olarak geri kalan statement_C.

Bu as-if kuralları volatiledeğişkenler için geçerli değildir . volatileDeğişkenler ve işlevlerle ilgili olarak , bir uygulama tam olarak yapmasını söylediklerinizi ve tam olarak bir şeyler yapmasını söylediğiniz sırayla yapmalıdır.

Soyut makine spesifikasyonunun bir dezavantajı var: Yavaş. C ve C ++ 'ın diğer dillere göre olumlu bir yönü de oldukça hızlı olmalarıdır. Bu soyut makineler için kod yürütülmüşse durum böyle olmaz. Olarak -eğer kurallar C ve C ++ kadar hızlı olmasını sağlayacak şeylerdir.

ELI5 cevabı

derleyici bellek adresini "optimize etmez" ne anlama gelir?

Bir bellek adresini "optimize etmek" beş yıllık bir yeteneğin alanı içinde olmayan gelişmiş bir kavramdır. Uyumlu beş yaşındakiler tam olarak ne yapmaları gerektiğini söyleyin, daha fazla, daha az değil. İle volatile, uygulamaya beş gibi davranmasını söylüyorsunuz: Düşünme yok, süslü optimizasyon yok. Bunun yerine, uygulama kodun yapmasını istediği şeyi tam olarak yapmak zorundadır.


1

(olmayan) uçucu derleyici için kodun nasıl optimize edileceğine dair bir ipucudur (oluşturulan derleme kodu bakış açısından):

  • uçucu olmayan , geçerli derleyicinizin değişkenin nerede bulunacağına veya değişkenin değerinin bir alt rutine nasıl verileceğine karar verdiği anlamına gelir
    • sabit bellek adresinde,
    • yığın üzerinde [işlemcilerin geçerli yığın işaretine göre],
    • öbek üzerinde [işlemcilerin geçerli baz alıcısına göre],
    • bir işlemci kaydında,
    • ...
  • uçucu , derleyicinin değişkeni optimize edemeyeceği anlamına gelir, çünkü main-cpu-s kontrolünün dışında başka bir şey (yani ayrı bir io-işlemci) bu değeri değiştirebilir.

0

Cevaplar oldukça tutarlı görünüyor ama önemli bir noktayı kaçırıyor. Derleyiciye yer ayırmak istediğinizi söylüyorsunuz ve her erişim için, VEYA YAZIN yazarak, o erişimi gerçekleştirmesini istiyorsunuz. Herhangi bir nedenle bu erişimleri veya bu değişkeni optimize etmesini istemiyoruz.

Evet, bunun bir nedeni, başka biri bizim için bu değeri değiştirebilir. Başka bir neden de, bu değeri başka biri için değiştiriyor olmamızdır. Bizim için değiştiren ya da değiştirdiğimiz kişinin başkası olması donanım / mantık veya yazılım olabilir. Genellikle çıplak metal gömülü programlarda, donanıma yazarken veya donanıma yazarken kontrol ve durum kayıtlarına erişim tanımlamak için kullanılır. Yazılımın yanı sıra yazılımla konuşan diğer cevaplarda da açıklanmıştır.

Ayrıca, bir kod bölümünü zamanlamaya çalışıyorsanız ve söz konusu değişkenlerin (başlangıç ​​zamanı, bitiş zamanı ve fark) sadece değişken olması gereken uçucuları kullanmıyorsanız, erişimlerin ne zaman ve hangi sırada gerçekleştiğini kontrol etmek için kullanılan uçucuyu da göreceksiniz. Sonuna doğru hesaplanan derleyici, zaman ölçümlerinden birini hareket ettirmekte serbesttir (onları yerleştirdiğimiz yerde değil), uçucu ile yapamaz, ancak deneyim daha az olası olduğunu gösterir.

Bazen, sadece zaman yakmak için kullanıldığını göreceksiniz, basit bir ledli yanıp sönen, çıplak metalin merhaba dünyası, sadece insan gözünün led'i görmesi için zaman yakmak için çok sayıda sayıya sahip bir değişken için uçucu kullanabilir. durumu değiştir. Daha gelişmiş örnekler, zamanı yakmak için zamanlayıcıları veya diğer olayları kullanır.

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.