theo hat geschrieben:Sicher eine Angelegenheit des Compilers.
Ich frage mich aber, ob das ein Bug ist.
Wenn nicht, dann ist es auf jeden Fall eine inkompatibilität zu Delphi... (nach Bernds Tests)
Sowas habe ich noch nie gesehen, dass die Rekursion zweimal aufgerufen wird.
Hast du überhaupt noch einen Plan, was hier abgeht? Ich meine was nach was kommt?
Es hat auch eine ganze Weile gedauert, bis ich den Bug in so reiner Form wie in den crash-Funktionen separieren konnte.
Für Lexart habe ich eine Funktion geschrieben, die die Funktionswerte beliebiger Funktionen mit einer wesentlich schneller Geschwindigkeit berechnet als zuvor. Nur dummerweise hatte diese Funktion Probleme mit sehr einfachen Termen, z.B. '1+1+1+1+1+1+1+1+1' ergab obige Fehlerausgabe.
Die Fehlerhafte Routine sah dabei so aus:
Code: Alles auswählen
function TAnalyse.FunkWert_NM(funktion:TermTyp; XWert:extended; Pointer:cardinal):extended;
begin
CASE funktion.TFeld[Pointer].Opera OF
001: Result:=funktion.TFeld[Pointer].GlKoZa; //001=Zahl
002: Result:=XWert; //002=Variable
003: Result:=(-1)*FunkWert_NM(funktion,XWert,funktion.TFeld[Pointer].Argument[0]); //003=Negation
004: begin //004=Addition
Result:=FunkWert_NM(funktion,XWert,funktion.TFeld[Pointer].Argument[0])+FunkWert_NM(funktion,XWert,funktion.TFeld[Pointer].Argument[1]);
end;
005: begin //005=Multiplikation
Result:=FunkWert_NM(funktion,XWert,funktion.TFeld[Pointer].Argument[0])*FunkWert_NM(funktion,XWert,funktion.TFeld[Pointer].Argument[1]);
end;
// ... weitere Zeilen...
else Result:=1;
end;
end; //Funwert_NM
Die problematische Rekursion befand sich an 2 Stellen: nach 004 und 005.
Nach langem debuggen habe ich heute aus Verzweiflung dann das ausprobiert:
Code: Alles auswählen
function TAnalyse.FunkWert_NM(funktion:TermTyp; XWert:extended; Pointer:cardinal):extended;
var Arg0,Arg1:extended; //Zwischenspeicher
begin
CASE funktion.TFeld[Pointer].Opera OF
001: Result:=funktion.TFeld[Pointer].GlKoZa; //001=Zahl
002: Result:=XWert; //002=Variable
003: Result:=(-1)*FunkWert_NM(funktion,XWert,funktion.TFeld[Pointer].Argument[0]); //003=Negation
004: begin //004=Addition
Arg0:=FunkWert_NM(funktion,XWert,funktion.TFeld[Pointer].Argument[0]);
Arg1:=FunkWert_NM(funktion,XWert,funktion.TFeld[Pointer].Argument[1]);
Result:=Arg0+Arg1;
end;
005: begin //005=Multiplikation
Arg0:=FunkWert_NM(funktion,XWert,funktion.TFeld[Pointer].Argument[0]);
Arg1:=FunkWert_NM(funktion,XWert,funktion.TFeld[Pointer].Argument[1]);
Result:=Arg0*Arg1;
end;
// ... weitere Zeilen...
else Result:=1;
end;
end; //Funwert_NM
... und siehe, es funktionierte
Naja, und dann hab ich obige crash-Funktion zum Test verwendet.
PS
@monta: Wenn ich Lazarus-Code im nicht-vollen Editor editiere, gibts irgendwie einen Zeichensalat?