Daniel (root) schrieb:
>
1 | > (assign (dereference pdata) (add (dereference (incr pdata)) 1))
|
2 | >
|
3 | > (assign (dereference (incr pdata)) (add (dereference pdata) 1))
|
4 | >
|
>
> interessant ist, dass man in lispsyntax keine Zweideutigkeiten
> erzeugen kann.
Keine Ahnung wie das in Lisp ist. Ist es da exakt definiert in welcher
Reihenfolge Listen ausgewertet werden.
(assign a b)
ok es ist klar, dass sowohl a als auch b evaluiert werden müssen, ehe
der assign seine Arbeit tun kann.
Aber ist auch geregelt, ob zuerst eval(a) und dann eval(b) gemacht wird
oder umgekehrt, oder ist das freigestellt.
In C ist das freigestellt. D.h. ein "Lisp compiler - C-like" (ich hoffe
man versteht was ich damit meine), könnte
(assign (dereference pdata) (add (dereference (incr pdata)) 1))
mit diesen Schritten implementieren
eval(dereference pdata)
eval(add (dereference (incr pdata)) 1)
assign
Er könnte aber auch
eval(add (dereference (incr pdata)) 1)
eval(dereference pdata)
assign
implementieren. Damit hast du schon mal einen Teil des undefinierten
Verhaltens. In C-Speak: Es ist nicht festgelegt, ob zuerst der rechte
oder der linke Teil bei einer Zuweisung ausgewertet wird oder gar eine
Mischung aus beidem.
Der andere Teil des undef. Verhaltens kommt daher, dass nicht festgelegt
ist, wann genau der Increment bei ++ zu erfolgen hat. C fordert
lediglich, dass dieser Nebeneffekt spätestens beim nächsten Sequenzpunkt
(sequence point) abgeschlossen sein muss.
Sequence Points sind im wesentlichen
* alle ;
* Ein Funktionsaufruf
* fällt mir grade nicht ein
D.h. der Compiler darf in
*++pdata = *pdata+1;
den Inkrement von pData rumschieben wie er lustig ist. Die Anweisung
kann komplett abgearbeitet sein und pdata hat überall denselben Wert und
erst kurz bevor in der logischen Sequenz der ; kommt wird pdata auf den
nächsten Wert gesetzt. Ist eine Möglichkeit. Der Compiler kann den
increment von pdata aber auch vorziehen soweit er möchte (und es die
Datenflussanalyse erlaubt). Ob also deine rechte Seite in obiger
Zuweisung noch den vorhergehenden oder bereits den incrementierten Wert
von pdata sieht, ist nicht definiert.
Denn eines steht fest: Ein = ist kein Sequencepoint, auch wenn viele
das gerne implizit annehmen.