2012-03-29 18 views
57

volatile derleyiciye referansı optimize etmemesini söyler, böylece her okuma/yazma yazmaçta kayıtlı değeri kullanmaz, ancak gerçek bir bellek erişimi yapar. Bazı sıradan değişkenler için yararlı olduğunu anlıyorum ama volatile'un bir işaretçiyi nasıl etkilediğini anlamıyorum.Niçin "uçucu int * p" gibi bir uçtan uca işaretçi yararlıdır?

volatile int *p = some_addr; 
int a = *p; // CPU always has to load the address, then does a memory access anyway, right? 

o int *p = some_addr olarak ilan edilmişse ne fark var?

cevap

101

şeklinde

volatile int* p; 

bir işaretçi derleyici volatile olarak tedavi edecek bir int bir işaretçidir. Bu, derleyicinin, kaynak kodunda hiçbir şeyin bulunmadığını bildirmek için p'un değiştiğine işaret eden değişken için olası olabileceğini varsayacağı anlamına gelir. Örneğin, düzenli bir tam sayıya işaret edecek şekilde p ayarladıysam, okuyucusu *p okuduğum veya yazdığım her zaman, değerin beklenmedik bir şekilde değişmiş olabileceğinin farkındadır.

bir volatile int* için bir daha kullanım durumu yoktur: Bir intvolatile olarak, o zaman normal bir int* ile ona işaret etmemelidir beyan edin. Örneğin, bu kötü bir fikir:

volatile int myVolatileInt; 
int* ptr = &myVolatileInt; // Bad idea! 

Bunun nedeni C derleyicisi artık değişken ptrvolatile olduğunu tarafından işaret hatırlar, bu yüzden yanlış bir kayıtta *p değerini önbelleğe ihtimalidir . Aslında, C++ 'da, yukarıdaki kod bir hatadır. Bunun yerine, Şimdi

volatile int myVolatileInt; 
volatile int* ptr = &myVolatileInt; // Much better! 

yazmalı, derleyici ptr bir volatile int de puan, bu yüzden olmaz (ya da değil! Olmalı) optimize etmeyi deneyin *ptr aracılığıyla erişen hatırlar.

Son bir ayrıntı - sen tartışılan işaretçi bir volatile int bir göstericidir. Ayrıca yapabilirsiniz:

int* volatile ptr; 

Bu işaretçi kendisi derleyici bellekte işaretçi önbelleğe deneyin ya işaretçi değerini optimize etmeye gerektiği anlamına gelir ki, volatile olduğu belirtildiği için işaretçi kendisi

volatile int* volatile ptr; 

Bu işaretçi ve pointee hem beklenmedik bir şekilde değişti alabilir söylüyor: Bu canavar almak istiyorsanız birlikte bu birleştirebilirsiniz başka bir şey (donanım, başka bir iş parçacığı, vb) tarafından tayin olur belki . Derleyici işaretçiyi kendiliğinden optimize edemez ve neyin işaret edildiğini optimize edemez.

Bu yardımcı olur umarız!

+0

Bence "sen düzenli bir int ile işaret etmemelisin" demek istiyorsun " – markgz

+0

@ markgz- Whoops! Evet doğru. Sabit. – templatetypedef

+0

Bence C de bir hatadır, ama C derleyicileri tür uyumsuzluklarından şikayet etmeye daha az eğilimlidir. –

6

Bu kod volatile int *p = some_addr bir volatile int bir imleç bildirir. İşaretçinin kendisi volatile değil.

Eğer int yanı sıra uçucu olması işaretçi gerekli istenmeyen bir durumda

, kullanmak gerekir: Bunu kullanmak gerekir nerede

volatile int * volatile p; 

Ben bir durum düşünemiyorum .

+2

Örnek: I İşaretçiyi ve gösterdiği verileri değiştiren ISR kodunda 'ulaturucu uint8_t * volatil pData' kullanıyorum. İşaretçi ana kod tarafından ayarlanır ve her iki işaretçi ve veri daha sonra okunur. – Christoph

İlgili konular