Zwischenzeiger in der Besetzung müssen "const qualifiziert" sein - warum?

8

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 :

zu verwenden %Vor%

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.

    
ttsiodras 01.02.2018, 10:41
quelle

1 Antwort

2

Nun, Ich habe ein Ticket in GCC's Bugzilla [...] dazu ... und Joseph Myers erhoben hat mit einer lakonischen Antwort geantwortet:

  

Nein, GCC ist nicht verwirrt. Es heißt, dass es umwandlungssicher ist    uint32_t ** bis volatile uint32_t *const * , aber nicht um es zu konvertieren    volatile 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.

    
ttsiodras 04.02.2018, 13:23
quelle

Tags und Links