C: Bedingte Anweisung "if"

#7854629
Lesenswert?

Ist beides wirklich das gleiche. Auch in der Ausführung: Wenn a>b, dann wird c>d nicht mehr abgefragt/ausgeführt. a>b wird garantiert vor c>d abgefragt.

Bei einfachen Zahlen/Variablen ist das egal. Wenn c oder d jedoch Makro/Funktion/HW-Register sind, dann kann das wichtig sein. Und beide Versionen verhalten sich exakt gleich (solange a,b,c oder d kein Makro ist, dass irgendeine ganz andere Sache macht)

#7854680
Lesenswert?

Harald K. schrieb:

Tut es aber nicht, da eben von links nach rechts ausgewertet wird.

Genau. Man sollte Assoziativität und Abarbeitungsreihenfolge nicht in einen Topf werfen: "Precedence and associativity are independent from order of evaluation."

https://en.cppreference.com/w/c/language/operator_precedence

https://en.cppreference.com/w/c/language/eval_order

LG, Sebastian

Persönliche Seite #7854683
Lesenswert?

Harald K. schrieb:

Wastl schrieb:

Ist die Abarbeitung ohne Klammerung nicht von rechts nach links?

Nein.

1
> int *p;
2
> 
3
> p = NULL;
4
> 
5
> 
6
> if (p && *p == 4)
7
> {
8
> }
9
>

Würde von rechts nach links ausgewertet, stürzte das mit einer Nullpointer-Exception ab. Tut es aber nicht, da eben von links nach rechts ausgewertet wird.

Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end!

Etwas ausprobieren ist keine valide Taktik in C, weil es sein kann, dass du dabei undefined behaviour nutzt. Der Compiler geht davon aus, dass der Programmierer weiß was er tut. Dein Code darf kein undefined behaviour enthalten und der Compiler ist frei, unter dieser Annahme beliebige Optimierungen durchzuführen. Es kann sein, dass das mit deinem aktuellen Compiler und den aktuellen Einstellungen funktioniert und der Code genau das macht, was du erwartest. Genau so gut kann das irgendwann in der Zukunft aber auch nicht mehr so sein. Dann hast du einen fiesen Fehler in gut abgehangenem, getestetem und seit Jahren zuverlässigem Code.

(Das war nur als allgemeine Warnung gedacht, dein Beispiel ist ok. Ich gehe sogar davon aus, dass für genau diesen &&-Anwendungsfall die Compiler eine optimierte Implementierung haben.)

Persönliche Seite #7854708
Lesenswert?

Cyblord -. schrieb:

Tilo R. schrieb:

(Das war nur als allgemeine Warnung gedacht, dein Beispiel ist ok.

Und deshalb ist dein ganzes Post Unsinn.

sehe ich anders.

Es ist normal dass man Pointer auf NULL testet bevor man drauf zugreift.

Richtig, ich habe nichts gegenteiliges behauptet.

Und die Reihenfolge ist eben genau festgelegt und kein Zufall und kein undefined behaviour.

Richtig, ich habe nichts gegenteiliges behauptet.

Tilo R. schrieb:

Etwas ausprobieren ist keine valide Taktik in C

Das ist meine Kernaussage. Imho auch richtig, ich habe sie sogar begründet.

#7854734
Lesenswert?

Tilo R. schrieb:

Ich gehe sogar davon aus, dass für genau diesen &&-Anwendungsfall die Compiler eine optimierte Implementierung haben.

Das ist die "short circuit evaluation", die gibt es genauso beim logischen Oder.

1
int *p;
2

3
p = NULL;
4

5
if (!p || *p)
6
{
7
}

Auch das stürzt nicht ab, weil die Auswertung des logischen Oder nach dem ersten zutreffenden Element (hier: !p) abgebrochen wird.

https://de.wikipedia.org/wiki/Kurzschlussauswertung https://en.wikipedia.org/wiki/Short-circuit_evaluation

Persönliche Seite #7854786
Lesenswert?

Paar Anmerkungen zur Shortcut-Evaluation:

Wenn der zweite Teilausdruch in a && b keine Seiteneffekte hat, dann /darf/ der Compiler (bzw. der von ihm erzeugte Code) den Ausdruck auswerten, falls günstig. Beispiel:

1
void fun (void);
2

3
void call_fun (int a)
4
{
5
    if (a >= 10 && a <= 20)
6
        fun();
7
}

wird mit avr-gcc zu:

1
call_fun:
2
        sbiw r24,10
3
        sbiw r24,11
4
        brsh .L1
5
        rjmp fun
6
.L1:    ret

Man kann also die Teilausdrücke nicht mehr bestimmten Instruktion(sfolg)en zuordnen.

Nochn Hinweis zu C++: Shortcut Evaluation wird /nicht/ auf überladene Operatoren && und || angewandt.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren