Forum: Compiler & IDEs Wert einer Zuweisung !


von peter dannegger (Gast)


Lesenswert?

Ich hab mir mal gedacht, nutze die Sache, die mich beim AVR immer ärgert
(setze 1 damits 0 wird) und schon falle ich auf die Nase.

Wenn ich eine Zuweisung teste, müßte doch eine Kopie der Zuweisung
ausgewertet werden ?

Aber der Compiler liest das GIFR nochmal ein, was natürlich in die Hose
geht.

Hier mal der Code:


    if( PIND & 1<<PD2 || (GIFR &= 1<<INTF0) ){  // check hanging on SDA
low
 b2a:   82 99           sbic    0x10, 2 ; 16
 b2c:   06 c0           rjmp    .+12            ; 0xb3a
 b2e:   8a b7           in      r24, 0x3a       ; 58
 b30:   80 74           andi    r24, 0x40       ; 64
 b32:   8a bf           out     0x3a, r24       ; 58
 b34:   8a b7           in      r24, 0x3a       ; 58
 b36:   88 23           and     r24, r24
 b38:   29 f0           breq    .+10            ; 0xb44
      Timeout_sda = time;


Mit anderen Worten, man kann nicht eine Zuweisung testen, wenn das
Register nicht 100% identisch rücklesbar ist.


Peter

von Stefan Kleinwort (Gast)


Lesenswert?

Anderes Problem:
In diesem Beispiel verlässt Du Dich darauf, dass alle Teile in der
if-Abfrage ausgeführt werden. Ist der erste Teil (PIND & 1<<PD2) aber
true, dann wird sofort in den Ausführungsteil gesprungen (was übrigens
C-konform ist). Die Zuweisung (GIFR &= 1<<INTF0) wird also garnicht
ausgeführt, wenn (PIND & 1<<PD2) true ist!

Viele Grüße, Stefan

von A.K. (Gast)


Lesenswert?

@peter: So ist die Sprache C nun einmal definiert. Das Ergebnis einer
Zuweisung ist der Wert der linken Seite, d.h der Inhalt der Variablen
oder des Registers, nach der Zuweisung. Wenn die als "volatile"
deklariert ist, dann sagt das dem Compiler, dass er noch einmal lesen
muss. Jeder andere korrekte Compiler verhält sich genauso (z.B.
Microsoft, Digital Mars).

von Jörg Wunsch (Gast)


Lesenswert?

Btw., warum man 1 setzen muss, um ein Interrupt-Flag zu löschen, steht
in der FAQ.  Hat beim näheren Hinsehen richtig Sinn.

von Peter D. (peda)


Lesenswert?

@Jörg,

"warum man 1 setzen muss..."

ja, daß weiß ich längst, ärgere mich jedesmal darüber.

Ich wollte ja nur das Testen und Löschen in einem Abwasch erledigen.

Aber das Beispiel hat mir gezeigt, daß Mehrfachzuweisungen sehr
gefährlich sein können und deshalb besser vermieden werden sollten.

Ein hübsches Beispiel ist noch:

x = UDR = y:

Dann enthält x alles mögliche, aber bloß nicht den Wert von y.

Peter

von Peter D. (peda)


Lesenswert?

@Stefan,

das ist korrekt und auch so gewollt.

Der richtige Code sieht jetzt so aus:

 if( PIND & 1<<PD2 || GIFR & 1<<INTF0 ){
   GIFR = 1<<INTF0;


Peter

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.