Forum: Mikrocontroller und Digitale Elektronik C Verständnisproblem Variable sich selbst zuweisen


von Eta (Gast)


Lesenswert?

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;

von Marcel (Gast)


Lesenswert?

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.

von lalala (Gast)


Lesenswert?

vielleicht beschwert sich ja 'lint'

von Peter D. (peda)


Lesenswert?

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.

von Selbsternannter Weltverbesserer (Gast)


Lesenswert?

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

von Eta (Gast)


Lesenswert?

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ß

von Karol B. (johnpatcher)


Lesenswert?

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

von Eta (Gast)


Lesenswert?

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 :-)

von Amateur (Gast)


Lesenswert?

>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.

von Peter D. (peda)


Lesenswert?

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

von Thomas E. (thomase)


Lesenswert?

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
von Peter D. (peda)


Lesenswert?

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
von Rolf Magnus (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

von Thomas (Gast)


Lesenswert?

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.

von Eta (Gast)


Lesenswert?

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

von Thomas (Gast)


Lesenswert?

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.

von Eta (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.