Wenn wir eine Variable wie volatile
jedes Mal deklarieren, wenn der neue Wert aktualisiert wird.
Wenn wir eine Variable als deklarieren, const
wird der Wert dieser Variablen nicht geändert
Dann const volatile int temp;
Was ist die Verwendung von Deklarieren der Variablen temp
wie oben?
Was passiert, wenn wir als deklarieren const int temp
?
const volatile int temp;
im Blockbereich (dh im Inneren{ }
) verwenden, es hat dort keine Verwendung.Antworten:
Ein als markiert gekennzeichnetes Objekt
const volatile
darf vom Code nicht geändert werden (ein Fehler wird aufgrund desconst
Qualifizierers ausgelöst) - zumindest durch diesen bestimmten Namen / Zeiger.Der
volatile
Teil des Qualifizierers bedeutet, dass der Compiler den Zugriff auf das Objekt nicht optimieren oder neu anordnen kann.In einem eingebetteten System wird dies normalerweise verwendet, um auf Hardwareregister zuzugreifen, die von der Hardware gelesen und aktualisiert werden können, aber keinen Sinn zum Schreiben haben (oder möglicherweise ein Fehler zum Schreiben sind).
Ein Beispiel könnte das Statusregister für eine serielle Schnittstelle sein. Verschiedene Bits zeigen an, ob ein Zeichen darauf wartet, gelesen zu werden, oder ob das Übertragungsregister bereit ist, ein neues Zeichen aufzunehmen (dh - es ist leer). Jeder Lesevorgang dieses Statusregisters kann zu einem anderen Wert führen, je nachdem, was sonst noch in der Hardware der seriellen Schnittstelle aufgetreten ist.
Es macht keinen Sinn, in das Statusregister zu schreiben (abhängig von der jeweiligen Hardwarespezifikation), aber Sie müssen sicherstellen, dass jeder Lesevorgang des Registers zu einem tatsächlichen Lesevorgang der Hardware führt - unter Verwendung eines zwischengespeicherten Werts aus einem zuvor gewonnenen Lesevorgang. ' Sie informieren Sie nicht über Änderungen im Hardwarestatus.
Ein kurzes Beispiel:
Wenn diese Zeiger nicht als solche markiert
volatile
wären, könnten einige Probleme auftreten:*recv_reg
von der Schleife geändert wurde, gibt es keinen Grund, warum sie vor dem Eintritt in die Schleife nicht gelesen werden kann.Die
volatile
Qualifizierer stellen sicher, dass diese Optimierungen nicht vom Compiler durchgeführt werden.quelle
volatile
wird den Compiler anweisen, den Code für die Variable nicht zu optimieren, normalerweise wenn wir wissen, dass sie von "außen" geändert werden kann, z. B. durch einen anderen Thread.const
teilt dem Compiler mit, dass es dem Programm verboten ist, den Wert der Variablen zu ändern.const volatile
ist eine ganz besondere Sache, die Sie wahrscheinlich genau 0 Mal in Ihrem Leben sehen werden (tm). Wie zu erwarten ist, bedeutet dies, dass das Programm den Wert der Variablen nicht ändern kann, der Wert jedoch von außen geändert werden kann, sodass keine Optimierungen an der Variablen durchgeführt werden.quelle
volatile
Variablen normalerweise das sind, was passiert, wenn Sie anfangen, mit Hardware zu spielen, nicht mit anderen Threads. Wo ich gesehen habeconst volatile
, ist in Dingen wie speicherabgebildeten Statusregistern oder dergleichen verwendet.Nicht weil die Variable const ist, hat sie sich möglicherweise nicht zwischen zwei Sequenzpunkten geändert.
Konstanz ist ein Versprechen, dass Sie den Wert nicht ändern, nicht, dass der Wert nicht geändert wird.
quelle
const
Daten nicht "konstant" sind.Ich musste dies in einer eingebetteten Anwendung verwenden, in der sich einige Konfigurationsvariablen in einem Bereich des Flash-Speichers befinden, der von einem Bootloader aktualisiert werden kann. Diese Konfigurationsvariablen sind zur Laufzeit 'konstant', aber ohne das flüchtige Qualifikationsmerkmal würde der Compiler so etwas optimieren ...
... durch Vorberechnung des Konstantenwerts und Verwendung einer sofortigen Montageanweisung oder Laden der Konstante von einem nahe gelegenen Ort, sodass Aktualisierungen des ursprünglichen CANID-Werts im Konfigurations-Flash-Bereich ignoriert werden. CANID muss konstant flüchtig sein.
quelle
In C sind const und volatile Typqualifizierer und diese beiden sind unabhängig.
Grundsätzlich bedeutet const, dass der Wert vom Programm nicht geändert werden kann.
Und volatil bedeutet, dass sich der Wert plötzlich ändert (möglicherweise von außerhalb des Programms).
Tatsächlich erwähnt der C-Standard ein Beispiel für eine gültige Deklaration, die sowohl konstant als auch flüchtig ist. Das Beispiel ist
"Externe const volatile int real_time_clock;"
Dabei kann real_time_clock von der Hardware geändert werden, jedoch nicht zugewiesen, erhöht oder dekrementiert werden.
Wir sollten also const und volatile bereits getrennt behandeln. Außerdem gilt dieses Typqualifikationsmerkmal auch für struct, union, enum und typedef.
quelle
Sie können const und volatile zusammen verwenden. Wenn beispielsweise angenommen wird, dass 0x30 der Wert eines Ports ist, der nur durch externe Bedingungen geändert wird, würde die folgende Deklaration die Möglichkeit versehentlicher Nebenwirkungen verhindern:
quelle
const
bedeutet, dass die Variable nicht durch den c-Code geändert werden kann, nicht, dass sie nicht geändert werden kann. Dies bedeutet, dass keine Anweisung in die Variable schreiben kann, ihr Wert sich jedoch möglicherweise noch ändert.volatile
bedeutet, dass sich die Variable jederzeit ändern kann und daher keine zwischengespeicherten Werte verwendet werden können; Jeder Zugriff auf die Variable muss an ihrer Speicheradresse ausgeführt werden.Da die Frage mit "eingebettet" gekennzeichnet ist und angenommen wird, dass
temp
es sich um eine vom Benutzer deklarierte Variable handelt, nicht um ein hardwarebezogenes Register (da diese normalerweise in einer separaten .h-Datei behandelt werden), sollten Sie Folgendes berücksichtigen:Ein eingebetteter Prozessor, der sowohl einen flüchtigen Lese- / Schreibdatenspeicher (RAM) als auch einen nichtflüchtigen Nur-Lese-Datenspeicher aufweist, beispielsweise einen FLASH-Speicher in einer von-Neumann-Architektur, in dem Daten- und Programmraum einen gemeinsamen Daten- und Adressbus gemeinsam nutzen.
Wenn Sie
const temp
einen Wert deklarieren (zumindest wenn dieser von 0 abweicht), weist der Compiler die Variable einer Adresse im FLASH-Bereich zu, da er selbst dann, wenn er einer RAM-Adresse zugewiesen wurde, noch FLASH-Speicher benötigt, um den Anfangswert zu speichern Dies macht die RAM-Adresse zu einer Platzverschwendung, da alle Operationen schreibgeschützt sind.Als Folge:
int temp;
ist eine im RAM gespeicherte Variable, die beim Start (cstart) auf 0 initialisiert wird. Es können zwischengespeicherte Werte verwendet werden.const int temp;
ist eine in (schreibgeschützt) FLASH gespeicherte Variable, die zur Compilerzeit auf 0 initialisiert wird. Es können zwischengespeicherte Werte verwendet werden.volatile int temp;
ist eine im RAM gespeicherte Variable, die beim Start (cstart) auf 0 initialisiert wird. Zwischengespeicherte Werte werden NICHT verwendet.const volatile int temp;
ist eine in (schreibgeschützt) FLASH gespeicherte Variable, die zur Compilerzeit auf 0 initialisiert wird. Zwischengespeicherte Werte werden NICHT verwendetHier kommt der nützliche Teil:
Heutzutage haben die meisten Embedded-Prozessoren die Möglichkeit, Änderungen an ihrem schreibgeschützten nichtflüchtigen Speicher mithilfe eines speziellen Funktionsbausteins
const int temp
vorzunehmen. In diesem Fall können Änderungen zur Laufzeit vorgenommen werden, obwohl dies nicht direkt möglich ist. Auf andere Weise kann eine Funktion den Wert an der Adresse ändern, an der sietemp
gespeichert ist.Ein praktisches Beispiel wäre die Verwendung
temp
der Seriennummer des Geräts.temp
Wenn der eingebettete Prozessor zum ersten Mal ausgeführt wird, ist er gleich 0 (oder dem deklarierten Wert), und eine Funktion kann diese Tatsache verwenden, um einen Test während der Produktion auszuführen. Wenn dies erfolgreich ist, können Sie eine Seriennummer zuweisen und den Werttemp
von mittels ändern einer besonderen Funktion. Einige Prozessoren haben dafür einen speziellen Adressbereich mit OTP-Speicher (einmalig programmierbar).Aber hier kommt der Unterschied:
Wenn
const int temp
es sich um eine modifizierbare ID anstelle einer einmalig programmierbaren Seriennummer handelt und NICHT deklariert istvolatile
, wird möglicherweise ein zwischengespeicherter Wert bis zum nächsten Start verwendet, was bedeutet, dass die neue ID möglicherweise bis zum nächsten Neustart oder, noch schlimmer, einigen Funktionen nicht gültig ist verwendet möglicherweise den neuen Wert, während andere möglicherweise einen älteren zwischengespeicherten Wert bis zum Neustart verwenden. Wennconst int temp
IS deklariert istvoltaile
, wird die ID-Änderung sofort wirksam.quelle
Dieser Artikel beschreibt die Szenarien, in denen Sie konstante und flüchtige Qualifikationsmerkmale kombinieren möchten.
http://embeddedgurus.com/barr-code/2012/01/combining-cs-volatile-and-const-keywords/
quelle
In einfachen Worten, der Wert in der Variablen 'const volatile' kann nicht programmgesteuert geändert werden, sondern kann durch Hardware geändert werden. Flüchtig ist hier, um eine Compileroptimierung zu verhindern.
quelle
Wir verwenden das Schlüsselwort 'const' für eine Variable, wenn das Programm sie nicht ändern soll. Wenn wir eine Variable als 'const volatile' deklarieren, weisen wir das Programm an, sie nicht zu ändern, und den Compiler, dass diese Variable aufgrund von Eingaben aus der Außenwelt unerwartet geändert werden kann.
quelle