Guten Tag, ich versuche gerade einen Code zu verstehen. Warum gibt diese Zeile keinen Fehler, bzw. was macht der Compiler damit? uint8_t Dummy = Dummy;
uint8_t Dummy; Die Variable Dummy wird Speicheradresse x zugewiesen. Dummy = Dummy; Der Inhalt der Adresse x wird ausgelesen und an Adresse x gespeichert. Macht keinen Sinn, aber aus Sicht des Compilers ist alles in Ordnung.
Der Compiler kann es wegoptimieren, da Dummy nicht volatile ist. Beim AVR kann man damit z.B. pending Interrupts löschen. Und da die IO-Register volatile sind, muß er den Zugriff auch komplett durchführen.
Hallo, ich habe in dem Programmlisting eines ehemaligen Kollegen auch immer über Zeilen der Art "i = i" gewundert. Er hat sie nur eingefügt um an der betreffenden Programmzeile einen "Breakpoint" setzen zu können. Meist vor Schleifen oder dergleichen. Mit freundlichen Grüßen Selbsternannter Welverbesserer
Danke für Eure Antworten. Ich habe es rausgefunden. In den Dummy wird nur geschrieben um einen Speicher zu leeren -> Dummy. Dummy wird niemals gelesen -> Compiler Warnung. int Dummy = Dummy; -> Compiler Warnung weg. Dank und Gruß
Eta schrieb: > int Dummy = Dummy; > -> Compiler Warnung weg. Scheint mir die falsche Lösung für dieses Problem zu sein. Wie du selbst feststellen musstest ist das nicht selbstverständlich und ohne Rücksprache nur schwierig zu "erraten". Ein entsprechender Kommentar wäre an dieser Stelle also durchaus angebracht. Ansonsten: https://stackoverflow.com/questions/3417837/what-is-the-best-way-to-supress-unused-variable-x-warning
Karol Babioch schrieb: > Eta schrieb: >> int Dummy = Dummy; >> -> Compiler Warnung weg. > > Scheint mir die falsche Lösung für dieses Problem zu sein. Wie du selbst > feststellen musstest ist das nicht selbstverständlich und ohne > Rücksprache nur schwierig zu "erraten". Ein entsprechender Kommentar > wäre an dieser Stelle also durchaus angebracht. > > Ansonsten: > > https://stackoverflow.com/questions/3417837/what-i... Ja ein Kommentar ist nicht schlecht... der Link ist ein bisschen mit Kanonen auf Spatzen. Weitere Kritik bitte direkt an NXP von denen ist der Code :-)
>In den Dummy wird nur geschrieben um einen >Speicher zu leeren -> Dummy. Üblicherweise wird bei solch einfachen Befehlen die Quelle nicht verändert. Der Wert in "Dummy" ist nach dem Lesen und anschließendem Schreiben, der Gleiche wie vorher.
Eta schrieb: > Ich habe es rausgefunden. In den Dummy wird nur geschrieben um einen > Speicher zu leeren -> Dummy. Wie soll das gehen? Beim AVR-GCC wird das knallhart wegoptimiert, da nicht volatile:
1 | void test() |
2 | {
|
3 | uint8_t Dummy = Dummy; |
4 | }
|
5 | 22: 08 95 ret |
Eta schrieb: > Dummy wird niemals gelesen -> Compiler Warnung. > int Dummy = Dummy; > -> Compiler Warnung weg. Glückwunsch. Du hast eine Variable, die nie benutzt und deswegen wegoptimiert wird und der Compiler gibt keine Warnung aus. Toll. Lässt sich auch so lösen:
1 | //int Dummy;
|
oder so:
Ohne Optimierung wird die Variable allerdings angelegt
1 | int Dummy; |
erzeugt aber eine Warnung, daß sie nicht initialisiert ist.
1 | int Dummy = 0; |
intitilaisiert die Variable, kostet aber Code.
1 | int Dummy = Dummy; |
hingegen initialisiert die Variable mit sich selbst. Da kommt der Compiler sogar ohne Optimierung drauf, daß an dieser Stelle nichts zu tun ist. Somit wird hier auch kein weiterer Code erzeugt. Spart also Speicher und steigert die Performance. Voraussetzung ist natürlich, daß die Varable danach auch benutzt wird. Sonst macht das keinen Sinn. Bei eingeschalteter Optimierung sieht das Ganze allerdings anders aus. mfg.
:
Bearbeitet durch User
Da Du uns hartnäckig den Kontext verweigerst, vermute ich mal, Du willst einen Puffer leeren. Dann braucht man keine Dummy-Variable, da in C jeder Ausdruck einen Wert hat, d.h. einen Lesezugriff impliziert. Z.B. Leeren des UART-Puffers beim AVR:
1 | void flush_rxd() |
2 | {
|
3 | while( UCSRA & 1<<RXC ) |
4 | UDR; |
5 | }
|
erzeugt:
1 | void flush_rxd() |
2 | {
|
3 | 34: 01 c0 rjmp .+2 ; 0x38 <flush_rxd+0x4> |
4 | while( UCSRA & 1<<RXC ) |
5 | UDR; |
6 | 36: 8c b1 in r24, 0x0c ; 12 |
7 | 38: 5f 99 sbic 0x0b, 7 ; 11 |
8 | 3a: fd cf rjmp .-6 ; 0x36 <flush_rxd+0x2> |
9 | }
|
10 | 3c: 08 95 ret |
Die Compilerwarnungen auszutricksen, gehört sich nicht. Im Team gibts da gehörig was auf die Finger.
:
Bearbeitet durch User
Thomas Eckmann schrieb: > Ohne Optimierung wird die Variable allerdings angelegtint Dummy; > erzeugt aber eine Warnung, daß sie nicht initialisiert ist. Aber nur, wenn sie auch später nicht geschrieben wird, bevor sie zum ersten mal gelesen wird. Thomas Eckmann schrieb: > Voraussetzung ist natürlich, daß die Varable danach auch benutzt wird. > Sonst macht das keinen Sinn. Wenn sie nachher benutzt wird, ist es genauso sinnlos. Dann wirklich initialisiert ist sie ja immer noch nicht. Dazu muß sie irgendwann mal geschrieben werden. Da macht's keinen Unterschied, ob ich sie bei der Definition erstmal uninitialisiert lasse oder mit sich selbst initialisiere.
Rolf Magnus schrieb: > Dann wirklich > initialisiert ist sie ja immer noch nicht. Der Compiler ist kein Mensch und prüft nur formal, ob eine Initialisierung und ein Lesen erfolgt. Aber dieses hier ist Verarsche^3 und verstößt gehen MISRA oder jeden anderen Firmenstandard. Die Compilerbauer hatten solch ein Konstrukt definitiv nicht im Sinn. Ein Ausdruck ohne Zuweisung ist dagegen regulär und jeder weiß sofort, was er bewirkt.
Eta schrieb: > Guten Tag, > > ich versuche gerade einen Code zu verstehen. > Warum gibt diese Zeile keinen Fehler, bzw. was macht der Compiler damit? > uint8_t Dummy = Dummy; Der Compiler kann damit machen, was er will, der Code ist undefiniert. Also zum Beispiel Deine Festplatte formatieren.
Hallo liebe Freunde, immer locker bleiben :-D. Bevor Peter explodiert.... der Code ging noch weiter :-) Peter Dannegger schrieb: > Da Du uns hartnäckig den Kontext verweigerst, vermute ich mal, Du willst > einen Puffer leeren. So weit dachte ich nicht... Asche auf mein Haupt. So und nun zu Eurer Befriedigung:
1 | uint8_t Dummy = Dummy; |
2 | .....
|
3 | Dummy = LPC_UART1->RBR; /* Dummy read on RX to clear |
4 | interrupt, then bail out */
|
Zufällig gesehen und gewundert auf: http://www.lpcware.com/content/forum/receiving-uart-in-lpc1768
Eta schrieb: > > uint8_t Dummy = Dummy; > ..... > Dummy = LPC_UART1->RBR; /* Dummy read on RX to clear > interrupt, then bail out */ > > Zufällig gesehen und gewundert auf: > http://www.lpcware.com/content/forum/receiving-uart-in-lpc1768 Ein einfaches
1 | LPC_UART1->RBR; |
hätte es auch getan.
Jo, das hat Peter auch schon geschrieben ... Tut mir leid. Ist wieder gut? Ich habs nur gesehn und mich gewundert, da nicht verstanden. Geh jetzt wieder Ostereier färben, das kann ich besser :-) Frohe Ostern Euch allen und immer friedlich, die Familie kommt erst morgen :-P
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.