aktualisieren 18. Februar 2017
Die Antwort unten zitiert & diskutiert die Sprache in der Norm, einige widersprüchliche Sprache in der Begründung und einige Kommentare von gnu.cc Wieder den Widerspruch. Es gibt einen Fehlerbericht, der im Wesentlichen eine Committee-Vereinbarung enthält (obwohl noch offen), dass der Standard sagen sollte, und dass die Absicht immer gewesen ist, und dass Implementierungen immer reflektiert haben, dass es nicht die Volatilität von eines Objekts ist (nach dem Standard) aber der Volatilität von (der Wert von) ein Zugriff (per der Rationale). (Credit Olaf für diesen DR zu erwähnen.)
Defect Report Summary für C11 Version 1.10 Datum: April 2016 DR 476 volatile semantics for lvalues 04/2016 Offene
Nr Da das zugegriffen Objekt nicht flüchtig ist.
Objekt p
ist vom Typ Zeiger auf flüchtige int. Aber x
ist kein Objekt eines Typs mit flüchtiger Qualifizierung. Die Qualifikationen auf p beeinflussen, welche Zugriffe durch sie ausgeführt werden können, beeinflussen jedoch nicht den Typ des Objekts, auf das es verweist. Es gibt keine Einschränkung für den Zugriff auf ein nicht-qualifiziertes Objekt über einen flüchtigen lvalue.Der Zugriff auf x durch p ist also kein Zugriff auf ein Objekt mit einem flüchtigen Typ.
(siehe 6.7.3 Typ Qualifikation für die Einschränkungen für Objekte von qualifizierten Typen zugreifen. Er sagt, Sie nicht nur ein flüchtiges qualifiziertes Objekt über einen uneingeschränkten lvalue zugreifen können.)
Auf der anderen Seite, this post Zitate aus dem 6.7.3 der Rationale für den Internationalen Standard - Programmiersprachen - C:
Eine Umwandlung eines Wertes in einen qualifizierten Typ hat keine Auswirkung; Die Qualifizierung (flüchtig, sagen wir) kann keine Auswirkung auf den Zugriff haben, da es vor dem Fall aufgetreten ist. Wenn auf ein nichtflüchtiges Objekt mit flüchtiger Semantik zugegriffen werden muss, besteht die Technik darin, die Adresse des Objekts in den entsprechenden Zeiger für den qualifizierten Typ zu konvertieren und dann den Zeiger diesen Wert zu dereferenzieren.
Allerdings kann ich im Standard keine Sprache finden, die besagt, dass die Semantik auf dem Lvalue-Typ basiert. Von gnu.org:
Ein Bereich, der Verwirrung ist die Unterscheidung zwischen Objekten mit flüchtigen Typen definiert und flüchtigen lvalues. Vom Standpunkt des C-Standards mit der Ansicht aus hat ein Objekt, das mit einem flüchtigen Typ definiert ist, äußerlich sichtbares Verhalten . Sie können sich an solche Objekte denken, die kleine Oszilloskop-Sonden haben, so dass der Benutzer einige Eigenschaften von Zugriffen auf sie beobachten kann, genau wie der Benutzer Daten beobachten kann, die in Ausgabedateien geschrieben wurden. Der Standard macht jedoch nicht deutlich, ob Benutzer Zugriffe durch flüchtige Werte auf gewöhnliche Objekte beobachten können.
[..] Aus dem Standard ist nicht klar, ob volatile lvalues allgemein mehr Garantien bieten als nichtflüchtige lvalues, wenn die zugrunde liegenden Objekte gewöhnlich sind.
Nein, denn es gibt keine Nebenwirkungen:
Auch wenn die Semantik von *p
dass ein flüchtigen sein muß, der Standard dennoch sagt:
5.1.2.3 Programmausführung 4 In der abstrakten Maschine werden alle Ausdrücke wie in der Semantik angegeben ausgewertet. Eine tatsächliche Implementierung muss einen Teil eines Ausdrucks nicht auswerten, wenn er daraus ableiten kann, dass sein -Wert nicht verwendet wird und keine erforderlichen Nebenwirkungen erzeugt werden (einschließlich aller durch Aufruf einer Funktion oder Zugriff auf ein flüchtiges Objekt ).
Auch hier gibt es kein flüchtiges Objekt in Ihrem Code. Obwohl eine Kompilierungseinheit, die nur sieht, konnte diese Optimierung nicht vornehmen.
Denken Sie auch daran
6.7.3 Typ-Qualifikation 7 [...] Was einen Zugriff auf ein Objekt mit einem Typ mit flüchtiger Qualifizierung ausmacht, ist implementierungsdefiniert.
5.1.2.3 Programmausführung 8 Strengere Korrespondenzen zwischen abstrakten und tatsächlichen Semantik kann durch jede Implementierung definiert werden.
So bloßen Erscheinungen von flüchtigen lvalues Ihnen nicht sagen, was "Zugänge" gibt es. Sie haben nicht das Recht, über "den einfachen Zugang zu *p
von tmp = *p
" zu sprechen, mit Ausnahme des dokumentierten Implementierungsverhaltens.
Ein konformes Programm kann den Unterschied nicht erkennen, da der Zugriff auf und die Änderung von 'x' keine beobachtbaren Nebenwirkungen sind. Daher kann der Compiler unter "Als-ob-Regel" optimieren. –
@IgorTandetnik: Das ist die Art und Weise, wie ich es interpretiere, aber es scheint keine populäre Theorie zu sein, und ich frage immer noch, ob es richtig ist. Wenn auf x nicht zugegriffen wird, außer als "* (volatile int *) & x", und "& x" wird für Hardware sichtbar gemacht, die darauf zugreift, oder wenn "sig_atomic_t" ist "int" und "* (volatile int *) & x Wird von einem Signal-Handler zugegriffen, gibt es dann möglicherweise wahrnehmbare beobachtbare Nebenwirkungen? –
Wenn die Hardware auf x zugreift und Sie sie als nichtflüchtig deklarieren, implementiert die Hardwarekonfiguration die virtuelle C-Maschine nicht. – philipxy