570 Stimmen

Warum wird volatile in C benötigt?

Warum ist volatile in C benötigt? Wofür wird es verwendet? Was wird es tun?

33voto

Meine einfache Erklärung ist:

In einigen Szenarien optimiert der Compiler auf der Grundlage der Logik oder des Codes die Variablen, von denen er annimmt, dass sie sich nicht ändern. Die volatile Schlüsselwort verhindert, dass eine Variable optimiert wird.

Zum Beispiel:

bool usb_interface_flag = 0;
while(usb_interface_flag == 0)
{
    // execute logic for the scenario where the USB isn't connected 
}

Aus dem obigen Code könnte der Compiler denken usb_interface_flag als 0 definiert ist und in der while-Schleife für immer Null sein wird. Nach der Optimierung behandelt der Compiler sie als while(true) ständig, was zu einer Endlosschleife führt.

Um diese Art von Szenarien zu vermeiden, deklarieren wir das Flag als flüchtig. Damit teilen wir dem Compiler mit, dass dieser Wert von einer externen Schnittstelle oder einem anderen Programmmodul geändert werden kann, d.h. bitte nicht optimieren. Das ist der Anwendungsfall für volatile.

20voto

Alexandre C. Punkte 53706

Eine marginale Verwendung für flüchtige Stoffe ist die folgende. Angenommen, Sie wollen die numerische Ableitung einer Funktion berechnen f :

double der_f(double x)
{
    static const double h = 1e-3;
    return (f(x + h) - f(x)) / h;
}

Das Problem ist, dass x+h-x ist im Allgemeinen nicht gleich h aufgrund von Rundungsfehlern. Denken Sie darüber nach: Wenn Sie sehr nahe beieinander liegende Zahlen subtrahieren, verlieren Sie viele signifikante Ziffern, was die Berechnung der Ableitung ruinieren kann (denken Sie an 1,00001 - 1). Eine mögliche Abhilfe könnte sein

double der_f2(double x)
{
    static const double h = 1e-3;
    double hh = x + h - x;
    return (f(x + hh) - f(x)) / hh;
}

aber je nach Plattform und Compiler-Switches kann die zweite Zeile dieser Funktion durch einen aggressiv optimierenden Compiler ausgelöscht werden. Sie schreiben also stattdessen

    volatile double hh = x + h;
    hh -= x;

um den Compiler zu zwingen, den Speicherplatz zu lesen, der hh enthält, und damit eine eventuelle Optimierungsmöglichkeit zu verpassen.

11voto

Neo Cambell Punkte 119

Es gibt zwei Verwendungszwecke. Diese werden speziell in der Embedded-Entwicklung häufiger verwendet.

  1. Der Compiler optimiert nicht die Funktionen, die Variablen verwenden, die mit dem Schlüsselwort volatile definiert sind

  2. Flüchtig wird verwendet, um auf genaue Speicherplätze im RAM, ROM usw. zuzugreifen. Dies wird häufiger verwendet, um Geräte mit Speicherzuordnung zu steuern, auf CPU-Register zuzugreifen und bestimmte Speicherplätze zu finden.

Siehe Beispiele in der Baugruppenliste. Re: Verwendung des C-Schlüsselworts "volatile" in der Embedded-Entwicklung

11voto

Alexey Frunze Punkte 59460

Ich möchte noch ein weiteres Szenario erwähnen, bei dem flüchtige Stoffe eine Rolle spielen.

Angenommen, Sie ordnen eine Datei dem Speicher zu, um die E/A zu beschleunigen, und diese Datei kann sich im Hintergrund ändern (z. B. befindet sich die Datei nicht auf Ihrer lokalen Festplatte, sondern wird stattdessen von einem anderen Computer über das Netzwerk bereitgestellt).

Wenn Sie über Zeiger auf nichtflüchtige Objekte (auf Quellcodeebene) auf die Daten der Memory-Mapped-Datei zugreifen, kann der vom Compiler erzeugte Code dieselben Daten mehrfach abrufen, ohne dass Sie dies bemerken.

Wenn sich diese Daten ändern, kann es passieren, dass Ihr Programm zwei oder mehr verschiedene Versionen der Daten verwendet und in einen inkonsistenten Zustand gerät. Dies kann nicht nur zu einem logisch falschen Verhalten des Programms führen, sondern auch zu ausnutzbaren Sicherheitslücken, wenn es nicht vertrauenswürdige Dateien oder Dateien von nicht vertrauenswürdigen Orten verarbeitet.

Wenn Ihnen die Sicherheit am Herzen liegt, und das sollten Sie, ist dies ein wichtiges Szenario, das Sie berücksichtigen sollten.

10voto

Diomidis Spinellis Punkte 18162

Volatile ist auch nützlich, wenn Sie den Compiler zwingen wollen, eine bestimmte Codesequenz nicht zu optimieren (z.B. beim Schreiben eines Micro-Benchmarks).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X