obenstehende Warnung kommt nach Umstieg auf eine aktuelle Arm GCC Version. Der Quellcode ist
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
Eigentlich habe ich temp extra auf volatile gesetzt weil es nicht mehr zurückgelesen wird. Warum dann die Warnung ?
|
Anzeige
|
GCC warning: variable 'temp' set but not usedobenstehende Warnung kommt nach Umstieg auf eine aktuelle Arm GCC Version. Der Quellcode ist
Eigentlich habe ich temp extra auf volatile gesetzt weil es nicht mehr zurückgelesen wird. Warum dann die Warnung ?
Gast
#6615918
J. V. schrieb: > Eigentlich habe ich temp extra auf volatile gesetzt ... aber lokal delariert, i.e. du kannst nur innerhalb der Sub auf sie zugreifen. leo Das volatile bewirkt hier nichts, da die Variable auf dem Stack liegt und damit ihre Adresse ausserhalb der Funktion nicht bekannt und auch nicht ermittelbar ist. Der Compiler ist also clever und glaubt dir nicht. In GCC kannst du aber die Variable direkt als unused deklarieren:
Das ist dann aber nicht auf andere Compiler übertragbar.
Gast
#6615927
temp = USART1->SR; Dir fehlt z.b. ein xxx = temp oder so was ähnliches Einfach gesagt. Und weißt einer Variable einen wert zu ABER du benutzt diese Variable im Code (dieser Sub) nicht mehr. Ist du Variable Public deklariert, muss du sie irgendwo im Code wieder Auslesen o. benutzen. Ist sie es nicht, musst du sie in der Sub (hier void) benutzen. Das ist eine "Hast du nicht was vergessen" Warnung. >... aber lokal delariert, i.e. du kannst nur innerhalb der Sub auf sie >zugreifen. >leo Er benutzt temp schlicht nicht. Den Rest interpretierst du wieder mal rein. Thomas F. schrieb: > In GCC kannst du aber die Variable direkt als unused deklarieren: Dazu muss man nicht erst in die GCC-Trickkiste greifen. Geht einfach so:
Gast
#6615952
Jonas B. schrieb: > Er benutzt temp schlicht nicht. ... nur schreibend, ja. Ist ja offensichtlich. > Den Rest interpretierst du wieder mal > rein. What? Welchen Rest? Was sollte ich da interpretieren? leo >Was sollte ich da interpretieren? Das er außerhalb drauf zugreift. >i.e. du kannst nur innerhalb der Sub auf sie >zugreifen. Jörg W. schrieb: sinngemäß > Dazu muss man nicht erst in die GCC-Trickkiste greifen. > (void)USART1->SR; // SR-DR Lesesequenz setzt alle Flags zurueck > (void)USART1->DR; // wie offiziell ist denn das? Mein gcc 9.2 erzeugt übrigens auch ohne (void) den richtigen Code. Wie offiziell wäre denn das? Bauform B. schrieb: > wie offiziell ist denn das? Ganz und gar :-) > Mein gcc 9.2 erzeugt übrigens auch ohne (void) den richtigen Code. Wie > offiziell wäre denn das? Genauso. Kann aber halt sein, wenn man die Warnungen besonders pingelig stellt, dass einem dann jemand sagt, dass man das Ergebnis des Ausdrucks nicht benutzt. Mit dem Cast nach "void" sagt man ganz explizit "ich weiß, dass es hier einen Wert gibt, aber ich möchte den wegwerfen". Ist natürlich auch zur Dokumentation sinnvoll, das erübrigt dann Kommentare der Form "Register nur lesen, aber Wert wegwerfen". Das "(void)" drückt das Ganze viel kürzer aus. ;-) > (void)USART1->DR;
Als GCC Optimierer hätte ich sowas dann ganz wegoptimiert womit es dann
aber auch nicht mehr funktioniert wenn der Optimizer Schalter was
anderes als -O0 ist. Aber mit -Wall bin ich wohl auch selbst etwas
schuld am rumgemeckere. Morgen schau ich mir mal die globalen Variablen
an ob ich davon nicht was missbrauchen kann.
J. V. schrieb: > Als GCC Optimierer hätte ich sowas dann ganz wegoptimiert Wenn der Trottel, der die UART-Register definiert hat, sie nicht "volatile" deklariert hat, dann hast du Recht. Aber da derjenige wahrscheinlich kein Trottel war, steht es dem Optimierer halt nicht frei, diesen Teil wegzuwerfen, sondern er muss ihn schön brav ausführen und nur das Ergebnis verwerfen. > Aber mit -Wall bin ich wohl auch selbst etwas schuld am rumgemeckere. Nein. Industriestandard bei uns in der Firma: -Wall -Wextra -Werror. Wenn noch weitere sinnvolle Warnungen entdeckt werden, kommen diese gern noch dazu. (Wenn tatsächlich irgendwas nicht mehr frei von Warnungen damit compiliert, kann man sich als Ausnahme immer noch lokal mit einem Pragma helfen. Da steht dann aber auch 'ne Begründung dabei, warum das jetzt gerade so ist.) > Morgen schau ich mir mal die globalen Variablen an ob ich davon nicht > was missbrauchen kann. Mach doch nicht so'n Käse. Schreib den Typecast nach "void" davor, wie das jeder andere Embedded-Programmierer auch tut, und fertig ist die Laube – und das auch noch portabel (so portabel, wie Controller-Code halt sein kann). Ok, klar. Das volatile gehört natürlich an die Registerdefinition ran. Die hat im Übrigen STM gemacht und das schau ich mir morgen genauer an ob das so ok geht. Und -Wall bleibt auch wie immer dran J. V. schrieb: > Eigentlich habe ich temp extra auf volatile gesetzt weil es nicht mehr > zurückgelesen wird. Das volatile ändert nichts an der Tatsache, dass du den Inhalt von temp nicht benutzt, zwingt den Compiler aber, die Variable tatsächlich anzulegen, und zwar nicht etwa als Register, sondern im Hauptspeicher auf dem Stack. Dadurch wird nicht nur Stack-Speicherplatz verschwendet, der Compiler erzeugt darüberhinaus zwei unnötige Schreibzugriffe auf den Speicher und je nach Plattform zusätzlich noch Code für die Reservierung der Variable auf dem Stack. Ohne das volatile würde der Compiler die Variable und die Zugriffe darauf einfach wegoptimieren, aber die Warnung bleibt natürlich (zurecht) bestehen. Lass das temp deswegen einfach komplett weg und folge Jörgs Rat mit dem void-Cast. J. V. schrieb: > Die hat im Übrigen STM gemacht und das schau ich mir morgen genauer an > ob das so ok geht. Sicher geht das so OK. Ohne "volatile" würden all diese Hardware-Register schlicht nicht so funktionieren wie gewünscht, weil einem der Optimierer laufend in die Suppe spuckt – und genau das war ja auch der Grund, sowas wie "volatile" überhaupt einzuführen. Schon bei der PDP-11 (von der C her kommt) war es gang und gäbe, dass Geräteregister memory-mapped waren, also letztlich über Zeiger zugegriffen werden mussten. Bei STM sieht das ungefähr so aus. MCU-spezifische Datei:
Referenziert wird hier __IO, und das kommt aus den ARM-eigenen Definitionen. Die sehen so aus:
Da hast du nun dein "volatile". ;-) Aha, Danke - da muss ich nicht mal mehr selbst suchen.
Gast
#6616496
J. V. schrieb: > Aha, Danke - da muss ich nicht mal mehr selbst suchen. Müssen nicht. Tu es trotzdem. Einfach weil es wichtig ist. Normalerweise sollte dein Editor das anzeigen, wenn Du mit der Maus drüber bist. Falls nicht, bzw. falls es mehr als 4 Sekunden dauert, das zu finden, dann denke über eine IDE nach. >falls es mehr als 4 Sekunden dauert, das zu finden, >dann denke über eine IDE nach Ja das habe ich auch schon. Der Wunschkandidat heisst Eclipse. Das CDT Plugin scheint es ja auch in einer Embedded Version zu geben, die dann auch noch das Segger Kabel bzw. Ozone unterstüzt. Bis dahin gibt es aber noch ein paar weitere Nüsse zu knacken.
Gast
#6616827
J. V. schrieb: > Ja das habe ich auch schon. Der Wunschkandidat heisst Eclipse. > Das CDT Plugin scheint es ja auch in einer Embedded Version zu > geben, die dann auch noch das Segger Kabel bzw. Ozone unterstüzt. > Bis dahin gibt es aber noch ein paar weitere Nüsse zu knacken. oder CLion ??? Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|