Ein Zeiger des Formulars
volatile int* p;
ist ein Zeiger auf einen int
, den der Compiler als behandelt volatile
. Dies bedeutet, dass der Compiler davon ausgeht, dass sich die Variable, auf p
die zeigt, möglicherweise geändert hat, auch wenn der Quellcode nichts enthält, was darauf hindeutet, dass dies auftreten könnte. Wenn ich beispielsweise p
auf eine reguläre Ganzzahl verweise, ist *p
dem Compiler bei jedem Lesen oder Schreiben bewusst, dass sich der Wert möglicherweise unerwartet geändert hat.
Es gibt noch einen Anwendungsfall für a volatile int*
: Wenn Sie ein int
as deklarieren volatile
, sollten Sie nicht mit einem regulären darauf zeigen int*
. Zum Beispiel ist dies eine schlechte Idee:
volatile int myVolatileInt;
int* ptr = &myVolatileInt;
Der Grund dafür ist, dass sich der C-Compiler nicht mehr daran erinnert, dass die Variable, auf die gezeigt wird, ptr
is ist volatile
, sodass der Wert von *p
in einem Register möglicherweise falsch zwischengespeichert wird. In C ++ ist der obige Code ein Fehler. Stattdessen solltest du schreiben
volatile int myVolatileInt;
volatile int* ptr = &myVolatileInt;
Jetzt merkt sich der Compiler, dass ptr
er auf a zeigt, und volatile int
versucht daher nicht (oder sollte nicht!), Die Zugriffe durch zu optimieren *ptr
.
Ein letztes Detail - der Zeiger, den Sie besprochen haben, ist ein Zeiger auf a volatile int
. Sie können dies auch tun:
int* volatile ptr;
Dies besagt, dass der Zeiger selbst ist volatile
, was bedeutet, dass der Compiler nicht versuchen sollte, den Zeiger im Speicher zwischenzuspeichern oder den Zeigerwert zu optimieren, da der Zeiger selbst möglicherweise durch etwas anderes (Hardware usw.) neu zugewiesen wird. Sie können diese kombinieren zusammen, wenn Sie dieses Biest bekommen möchten:
volatile int* volatile ptr;
Dies besagt, dass sowohl der Zeiger als auch der Zeiger unerwartet geändert werden könnten. Der Compiler kann den Zeiger selbst nicht optimieren und er kann nicht optimieren, auf was gezeigt wird.
Hoffe das hilft!
do_something_else
ist. Wenn der Compiler vollständig davon überzeugt sein könnte, dass erdo_something_else
den Wert von nie geändert hatx
, könnte er den Wert von definitiv*p
aus einem Register lesen, wenn er dies wünscht. Ich bezweifle, dass dies für jeden vernünftigen Code und die meisten Compiler tatsächlich passieren würde, aber theoretisch wäre es möglich. Ist das sinnvoll?Dieser Code
volatile int *p = some_addr
deklariert einen Zeiger auf avolatile int
. Der Zeiger selbst ist nichtvolatile
.In dem unwahrscheinlichen Fall, dass der Zeiger sowohl flüchtig als auch int sein muss, müssen Sie Folgendes verwenden:
volatile int * volatile p;
Ich kann mir keine Situation vorstellen, in der Sie das brauchen würden.
quelle
Zur Nützlichkeit von flüchtigen Stoffen: Dies ist erforderlich, wenn Sie den Speicher überprüfen müssen, der von der Hardware wie einem seriellen Schnittstellencontroller geändert wird. Es hat seine Anwendung in der Welt der eingebetteten Systeme, in denen Sie sehr nah an der Hardware arbeiten, ohne dass ein Betriebssystem dazwischen liegt.
quelle