Was ist volatile (Typqualifizierer)?
Typqualifizierer in C, der dem Compiler mitteilt, dass sich der Wert einer Variablen außerhalb des sichtbaren Programms ändern kann (durch Peripherie, Interrupt-Handler usw.) oder dass schon das Lesen und Schreiben selbst eine Bedeutung hat. Zugriffe auf Objekte mit volatile werden weder weggelassen noch zusammengefasst, sondern in der geschriebenen Anzahl und Reihenfolge ausgeführt. Verwendet wird es für Register bei Memory-mapped I/O und für Flags, die mit einem Interrupt-Handler geteilt werden. Operationen atomar zu machen oder die Reihenfolge gegenüber anderen Kernen zu garantieren, leistet es nicht.
Japanische Bezeichnung: volatile(型修飾子)
„volatile (Typqualifizierer)“ kommt in 7 Übungsfragen aus 6 Themen vor, z. B. Grundlagen der Programmiersprache C, Betriebssystem und Hardware, Multicore und Synchronisation.
Fachgebiet: Grundlagen der Programmiersprache C
Was ohne volatile passiert
Ändert in einer Schleife wie while (flag == 0) { } nur ein Interrupt-Handler den Wert von flag, schließt der Compiler mitunter, dass sich flag in der Schleife nicht ändert, liest es nur einmal und macht daraus eine Endlosschleife. Dasselbe kann in einer Schleife passieren, die auf ein Statusregister der Peripherie wartet, und aufeinanderfolgende Schreibzugriffe auf dasselbe Register können zu einem zusammengefasst werden. Mit volatile wird so oft tatsächlich gelesen und geschrieben, wie es im Code steht.
Was volatile nicht leistet
volatile macht ein Read-Modify-Write nicht atomar; tritt mitten in *reg |= mask; ein Interrupt auf, kann die Änderung eines anderen Bits verloren gehen. Werte, die sich nicht in einem Zugriff lesen oder schreiben lassen, etwa eine 32-Bit-Variable auf einem 8-Bit-Mikrocontroller, können bei einer Unterbrechung teilweise schon den neuen Wert zeigen. Für die Synchronisierung zwischen Threads verwendet man Mechanismen, die Atomarität und Reihenfolge garantieren, etwa _Atomic aus C11 oder Sperren.
Häufige Fragen
Kann man const und volatile gleichzeitig angeben?
Ja. const volatile bedeutet „das Programm schreibt nicht hinein, aber der Wert ändert sich durch äußere Einflüsse und wird daher jedes Mal neu gelesen“ und wird etwa für schreibgeschützte Statusregister verwendet.
Wird ein Programm durch volatile langsamer?
Für die betreffende Variable ist die Optimierung, ihren Wert in einem Register zu halten, nicht mehr möglich; die Zahl der Zugriffe steigt, und es kann langsamer werden. Deshalb versieht man nicht alle Variablen damit, sondern nur die nötigen, etwa Peripherieregister und Variablen, die mit einem Interrupt-Handler geteilt werden.