Dlaczego wskaźnik point-to-volatile, jak "volatile int * p", jest przydatny?
volatile
ma powiedzieć kompilatorowi, aby nie optymalizował referencji, tak aby każdy odczyt/zapis nie wykorzystywał wartości zapisanej w rejestrze, ale miał rzeczywisty dostęp do pamięci. Rozumiem, że jest to przydatne dla jakiejś zwykłej zmiennej, ale nie rozumiem, jak volatile
wpływa na wskaźnik.
volatile int *p = some_addr;
int a = *p; // CPU always has to load the address, then does a memory access anyway, right?
Jaka jest różnica, jeśli została zadeklarowana jako int *p = some_addr
?
2 answers
Wskaźnik postaci
volatile int* p;
Jest wskaźnikiem do int
, który kompilator będzie traktował jako volatile
. Oznacza to, że kompilator założy, że zmienna, na którą wskazuje p
, może się zmienić, nawet jeśli w kodzie źródłowym nic nie wskazuje na to, że może to nastąpić. Na przykład, jeśli ustawiłem p
, aby wskazywał na zwykłą liczbę całkowitą, to za każdym razem, gdy czytam lub piszę *p
kompilator jest świadomy, że wartość mogła się nieoczekiwanie zmienić.
Tam jest jeszcze jeden przypadek użycia volatile int*
: jeśli zadeklarujesz int
jako volatile
, to nie powinieneś wskazywać na to zwykłym int*
. Na przykład, jest to zły pomysł:
volatile int myVolatileInt;
int* ptr = &myVolatileInt; // Bad idea!
Powodem tego jest to, że kompilator C nie pamięta już, że zmienna wskazywana przez ptr
jest volatile
, więc może niepoprawnie buforować wartość *p
w rejestrze. W rzeczywistości w C++ powyższy kod jest błędem. Zamiast tego powinieneś napisać
volatile int myVolatileInt;
volatile int* ptr = &myVolatileInt; // Much better!
Teraz kompilator pamięta, że ptr
wskazuje na volatile int
, więc nie będzie (lub nie powinno!) spróbuj zoptymalizować Dostęp poprzez *ptr
.
Ostatni szczegół - omawiany wskaźnik jest wskaźnikiem do volatile int
. Możesz również to zrobić:
int* volatile ptr;
To mówi, że wskaźnik sam jest volatile
, co oznacza, że kompilator nie powinien próbować buforować wskaźnika w pamięci ani optymalizować wartości wskaźnika, ponieważ sam wskaźnik może zostać przypisany przez coś innego (sprzęt, itp.) Możesz je ze sobą połączyć, jeśli podoba mi się ta bestia:
volatile int* volatile ptr;
To mówi, że zarówno wskaźnik, jak i wskaźnik mogą zostać nieoczekiwanie zmienione. Kompilator nie może zoptymalizować samego wskaźnika i nie może zoptymalizować tego, na co jest wskazywany.
Mam nadzieję, że to pomoże!Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-25 02:10:48
Ten kod volatile int *p = some_addr
deklaruje wskaźnik na volatile int
. Sam wskaźnik nie jest volatile
.
W mało prawdopodobnym przypadku, gdy wskaźnik musi być zmienny, a także int, musisz użyć:
volatile int * volatile p;
Nie wyobrażam sobie sytuacji, w której musiałbyś tego użyć.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-29 23:58:28