Forum: Compiler & IDEs Grundsatzfrage Vergleich bei While


von Manfred Schreier (Gast)


Lesenswert?

hi,

Ich verstehe etwas nicht und vielleicht kann mir jemand auf die Sprünge 
helfen.

Warum wird so;

  while(foo() && !(TWCR & (1<<TWINT)));

die Funktion foo() ausgeführt.
Und so ;

  while(!(TWCR & (1<<TWINT) && )foo());

nicht ??
danke

von Schleifchen (Gast)


Lesenswert?

Manfred Schreier schrieb:
> while(!(TWCR & (1<<TWINT) && )foo());

Sollte das eher so sein:
while(!(TWCR & (1<<TWINT) && foo()));

Das logische UND wird den zweiten Ausdruck nicht auswerten, wenn der 
erste schon false ergibt. Wenn also "!(TWCR & (1<<TWINT)" schon false 
ist, wird foo() micht mehr ausgewertet, und damit auch nicht aufgerufen.

von Andreas B. (andreas_b77)


Lesenswert?

Mal angenommen, die Klammer im zweiten Beispiel wäre korrekt gesetzt, 
wird bei Booleschen Operatoren in C nur soweit ausgewertet, bis das 
Ergebnis feststeht. Falls TWCR & (1<<TWINT) unwahr ist, wird die zweite 
Hälfte einer Und-Verknüpfung nicht ausgeführt.

Stichwort "short circuit operator".

von Schleifchen (Gast)


Lesenswert?

Schleifchen schrieb:
> Sollte das eher so sein:
> while(!(TWCR & (1<<TWINT) && foo()));

Typo, sollte sein:
while(!(TWCR & (1<<TWINT)) && foo());

von Udo S. (urschmitt)


Lesenswert?

Es ist generell gefährlich in logischen Ausdrücken Funktionen aufzurufen 
die noch mehr tun als nur einen Wert für den Ausdruck selbst zu 
ermitteln.
Generell werden logische Ausdrücke nur soweit ausgewertet bis das 
Ergebnis feststeht.
Das heisst:
Bei einem "oder" (or) wird der 2. Ausdruck nur dann garantiert 
ausgewertet wenn der Erste false ist
Bei einem "und" (and) wirde der 2. Ausdruck nur dann garantiert 
ausgewertet wenn der Erste true ist.

Deswegen goldene Regel:
Erst Funktionen aufrufen die etwas berechnen oder Anderes tun das später 
noch gebraucht wird
Erst dann den logischen Ausdruck auswerten.
Ist auch übersichtlicher

von Manfred Schreier (Gast)


Lesenswert?

foo() soll ein Flag überprüfen, das sozusagen mein Funktions Watchdog 
ist falls !(TWCR & (1<<TWINT) nie false wird.

Hab es aber noch nicht aus gerreift, da ich ein Binar timeslice schedule 
habe und der timer für meinen funktions WD schießt mir die ISR der 
TSlice zusammen :(

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Udo Schmitt schrieb:
> Es ist generell gefährlich in logischen Ausdrücken Funktionen aufzurufen
> die noch mehr tun als nur einen Wert für den Ausdruck selbst zu
> ermitteln.

Wenn man damit umzugehen weiß, ist es überhaupt nicht gefährlich, 
sondern sehr nützlich. Man spart sich damit überflüssige bzw. ungewollte 
Funktionsaufrufe.

von Rolf Magnus (Gast)


Lesenswert?

Udo Schmitt schrieb:
> Bei einem "oder" (or) wird der 2. Ausdruck nur dann garantiert
> ausgewertet wenn der Erste false ist
> Bei einem "und" (and) wirde der 2. Ausdruck nur dann garantiert
> ausgewertet wenn der Erste true ist.

Lasse das "garantiert" weg. Der 2.Ausdruck wird ausschließlich in den 
oben genannten Fällen ausgewertet und sonst nicht. Darauf kann man sich 
verlassen.

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.