Forum: Compiler & IDEs Zuweisung und unterschiedsprüfung in einem if


von LukasW (Gast)


Lesenswert?

Hallo!
Ich hätte mal eine Frage bzgl. C:
Ich habe eine recht aufwendige Berechnung für einen Wert in meinem 
System, bei dessen Änderung einmalig ein bestimmter Code ausgeführt 
werden soll.
Dazu habe ich mir folgenden Code überlegt:
1
void irgendeinefunktion()
2
{
3
   static unsigned char ucLastValue;
4
5
   if(ucLastValue != (ucLastValue = aufwendigeBerechnung()))
6
   {
7
      // Verarbeitung "wert geändert"
8
   }
9
}
Das scheint leider nicht richtig zu funktionieren, die Bedingung ist 
immer '0'. Nicht das ich keine Alternative wüsste, aber warum geht das 
nicht?

von x-beliebig (Gast)


Lesenswert?

x != x ist immer 0

von Karl H. (kbuchegg)


Lesenswert?

LukasW schrieb:

> Das scheint leider nicht richtig zu funktionieren, die Bedingung ist
> immer '0'. Nicht das ich keine Alternative wüsste, aber warum geht das
> nicht?

Weil in C nicht definiert ist, ob bei einem Vergleich zuerst die linke 
Seite und dann die rechte Seite oder umgekehrt ausgewertet wird. Der 
Compiler darf sich das aussuchen.

Du hast darauf spekuliert, dass zuerst die linke Seite ausgewertet wird, 
der Wert irgendwo temporär zwischengespeichert wird und erst dann der 
Funktionsaufruf erfolgt, der einen neuen Wert bringt welche gleichzeitig 
in ucLastValue gespeichert wird und mit dem alten Wert aus dem 
Zwischenspeicher verglichen wird.

Du hast mit Zitronen gehandelt.

Die einzigen paar Fälle in denen du in C von einer definierten 
Auswerte-Reihenfolge ausgehen kannst, sind &&, || und , (der 
Kommaoperator, nicht zu verwechseln mit dem Komma in Argumentlisten)

Ausdrücke mit diesen Operationen werden immer von links nach rechts 
ausgewertet. Aber abgesehen von diesen Operatoren solltest du in C 
niemals von einer in irgendeiner Art und Weise definierten 
Auswertereihenfolge ausgehen. Der Compiler hat in C ziemlich viele 
Freiheiten und darf sich die Reihenfolgen aussuchen wie sie ihm in den 
Kram passen.

von Der M. (steinadler)


Lesenswert?

Wie muss man denn die Denkweise verstehen?

Also ich würde das, wenn, dann so machen:
1
static unsigned char ucNewValue;
2
3
ucNewValue = aufwendigeBerechnung();
4
5
if(ucLastValue != ucNewValue)
6
{
7
   // Verarbeitung "wert geändert"
8
}
9
10
ucLastValue = ucNewValue;

Ich weiß, dass du keine Lösungsvorschläge haben willst, aber wie kommt 
man auf so ein merkwürdiges Konstrukt?

Ich finde, Zuweisungen in if-Abfragen sollte man sich eh abgewöhnen.
Habe vor kurzer Zeit verzweifelt nach einem Bug gesucht, bis ich gesehen 
hab, dass ich statt == nur ein = geschrieben hatte.

von Oliver (Gast)


Lesenswert?

Das ist ein typisches Beispiel, wie man Code schreibt, der aus völlig 
unverständlichen Gründen unsinnig trickreich und nicht selbsterklärend 
ist (und in diesem Fall auch noch nicht funktioniert).

Du möchtest den neuberechneten Wert mit dem aus dem vorherigen Zustand 
vergleichen,und den der Variablen ucLastValue zuweisen. Warum dann nicht 
einfach genau das hinschreiben, Zeile für Zeile, mit einer zusätzlichen 
lokalen Variablen, die den alten Wert von ucLastValue vor der 
Neuberechnung zwischenspeichert?
Denn wenn dein Ansatz funktioniert hätte, hätte der Compiler die auch 
anlegen müssen. Du sparst also mit deiner Trickserei weder Speicherplatz 
noch Rechenzeit.

Aber vielleicht ist das ja eine Übung für den obfuscated C contest.

Olvier

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.