Im folgenden Code ...
%Vor% ... der Compiler erkennt zu Recht, dass mögliche Zugriffe auf die Daten, auf die von p
in work
verwiesen wird, gefährliche Zugriffe sind. Wie es ist, weist der Code den Compiler an, dass es sicher ist, Code zu senden, der wiederholte Lesezugriffe auf *p
optimiert - was tatsächlich falsch ist.
Aber das Seltsame ist, dass die Warnung, die durch das Kompilieren dieses Codes ausgegeben wird ...
%Vor% ... beschweren sich nicht über den Verlust von volatile
- es empfiehlt stattdessen, const
:
Ich kann nicht sehen, wie const
hier Sinn macht.
P.S. Beachten Sie, dass das Hinzufügen von volatile
vor dem uint32_t *p
wie erwartet das Problem behebt. Meine Frage ist, warum der GCC const
anstelle von volatile
empfiehlt.
Nein, GCC ist nicht verwirrt. Es heißt, dass es umwandlungssicher ist
uint32_t **
bisvolatile uint32_t *const *
, aber nicht um es zu konvertierenvolatile uint32_t *
.
... und er fügte auch einen Verweis auf diesen Teil der C FAQ hinzu.
Ich muss zugeben, dass meine erste Reaktion darauf ein "sag was?" war. Ich habe den Vorschlag schnell getestet und den Code so geändert, dass er stattdessen die vorgeschlagene Deklaration (und Umwandlung) verwendet ...
%Vor%... und in der Tat, keine Warnung mehr.
Also ging ich weiter und las die relevanten FAQ - und ich glaube, ich verstehe ein bisschen mehr von dem, was passiert. Durch das Hinzufügen des Modifikators const
ist der übergebene Parameter (Lesen von rechts nach links, wie wir es bei dieser Art von C-Syntax tun sollten) :
ein Zeiger auf einen Zeiger constant (der sich niemals ändert), der auf flüchtige Daten zeigt
Das passt sehr gut zu dem, was hier passiert: Ich bekomme einen Zeiger, der auf flüchtige Daten zeigt, das ist ein von einem Treiber bereitgestellter Puffer - dh einen, den ich wirklich nicht ändern darf , da es aus vorbelegten Pufferlisten stammt, die der Treiber selbst zugewiesen hat. Das Ändern des Zeigers, den get_buffer_from_HW_driver
zurückgab, würde keinen Sinn ergeben; es ist nicht meins zu modifizieren, ich kann es nur so benutzen wie es ist.
Ich gebe zu, ich bin wirklich überrascht, dass das C-Typsystem (das durch die wirklich starken statischen Analyse-Checks von -Wcast-qual ergänzt wird) tatsächlich dazu beitragen kann, diese Semantik zu garantieren.
Vielen Dank an Joseph - und ich lasse die Frage für ein paar Wochen offen, für den Fall, dass jemand anderes mehr ausarbeiten möchte.
P.S. Eine mentale Notiz hinzufügen: Von nun an, wenn jemand behauptet, dass C eine einfache Sprache ist, denke ich, dass ich sie hier zeigen werde.