Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi lustiges problem mit dem compiler (?) (https://www.delphipraxis.net/135570-lustiges-problem-mit-dem-compiler.html)

arkon 13. Jun 2009 13:55


lustiges problem mit dem compiler (?)
 
folgender schöner quelltext:

Delphi-Quellcode:
function compvoc(Item1, Item2: Pointer): integer;
var
  t1,t2: extended;
begin
  t1:= TChVoc(Item1).coeff;
  t2:= TChVoc(Item2).coeff;
  if t1> t2then
    result := -1
  else
    result := 1;
//  Result := Round(TChVoc(Item1).coeff - TChVoc(Item2).coeff);
end;
wenn ich die if-abfrage ausklammere oder nur die letzte, ausgeklammerte zeile benutze funktioniert alles wunderbar. nur in der version, die oben steht, gibts nen zugriffsfehler. sicher, der eigentlich fehler liegt nicht hier sondern woanders. ABER: warum funktioniert "Result := Round(TChVoc(Item1).coeff - TChVoc(Item2).coeff);" aber nicht "if Round(TChVoc(Item1).coeff > TChVoc(Item2).coeff) then" !?!??!?!?
was zur hölle soll mir das sagen? compiler-optimierung ist schon ausgeschaltet.

mkinzler 13. Jun 2009 14:10

Re: lustiges problem mit dem compiler (?)
 
Wie sihet TChVoc aus?

arkon 13. Jun 2009 14:16

Re: lustiges problem mit dem compiler (?)
 
oh, sorry... ;)
Delphi-Quellcode:
  TChVoc = class
    public
...
      cgright: integer;
      cgwrong: integer;
      gcright: integer;
      gcwrong: integer;
      pgright: integer;
      pgwrong: integer;
...
      function coeff: extended;
  end;

function TChVoc.coeff: extended;
begin
//  Form1.Memo2.Lines.Add(pinyin);//+'|'+FloatToStr(result));
  case learningmode of
    cltPG: result := (pgwrong+1)/(pgwrong+pgright+1);
    cltGC: result := (gcwrong+1)/(gcwrong+gcright+1);
    cltCG: result := (cgwrong+1)/(cgwrong+cgright+1);
  else
    result := 0;
  end;
end;
also ein objekt. wenn ich die zeile in der coeff-fkt ausklammere, dann läuft er aus dem speicher raus. ergo wurde das objekt nicht initialisiert. das ganze ist in einer TLIst gespeichert und wird sortiert, daher kann ich nicht genau sagen wie das sortieren abläuft. aber das wird schon richtig sein ;). jedenfalls: direkt VOR dem sortieren kann ich noch fehlerfrei auf jeden eintrag der Liste zugreifen. trotzdem kommt er eine zeile später im nirvana an!?!?! vor allem aber: warum ist das verhalten bei den unterschiedlichen aufrufen so unterschiedlich? was spuckt der compiler hinten aus?
antwort: der compiler spuckt ganz zivilen assembler aus. im kritischen durchlauf ist jedoch item1 ein null-pointer. wadup?

jaenicke 13. Jun 2009 14:23

Re: lustiges problem mit dem compiler (?)
 
Zitat:

Zitat von arkon
was zur hölle soll mir das sagen?

Das hört sich sehr nach überschriebenem Speicher an. Benutzt du dynamische Arrays zum Beispiel? Dann schalte am besten einmal die Bereichsüberprüfung in den Compileroptionen an.

Hawkeye219 13. Jun 2009 14:29

Re: lustiges problem mit dem compiler (?)
 
Hallo,

wenn die Funktion eine Vergleichsroutine für einen Sortieralgorithmus darstellt, dann muss sie bei identischen Werten für die übergebenen Elemente den Wert 0 liefern. Die auskommentierte Zeile tut dies, die nicht auskommentierten Zeilen nicht.

Gruß Hawkeye

arkon 13. Jun 2009 14:35

Re: lustiges problem mit dem compiler (?)
 
hmmm... ich dachte, dass das nur die sortierung der liste beeinflussen würde. aber, siehe da: mit unterscheidung, ob die einträge gleich sind gibts keine fehler mehr. ?!?!? erstmal danke für die lösung, aber: warum macht tlist eine abfrage mit einem null-pointer wenn es die liste nicht sortiert kriegt? absicht? unkommentiert in jedemfall ;)

sx2008 13. Jun 2009 15:01

Re: lustiges problem mit dem compiler (?)
 
Zitat:

Zitat von arkon
folgender schöner quelltext:

Ne, der Quelltext ist nicht schön; er ist unschön!
1.) du sicherst deine Zeiger nicht mit Assert() ab
Delphi-Quellcode:
function compvoc(Item1, Item2: Pointer): integer;
var
  t1,t2: extended;
begin
  Assert(Assigned(Item1)); // der Rettungsschirm
  Assert(Assigned(Item2));
  t1:= TChVoc(Item1).coeff;
...end;
2.) Du hast doch schon eine Klasse.
Warum nicht eine Vergleichsfunktion einbauen?
Delphi-Quellcode:
TChVoc = class
public
...
  class function Compare(a,b:TChVoc):integer;
end;

...

function compvoc(Item1, Item2: Pointer): integer;
begin
  Assert(Assigned(Item1));
  Assert(Assigned(Item2));
  Result := TChVoc.Compare(TChVoc(Item1), TChVoc(Item2));
end;

Apollonius 13. Jun 2009 15:11

Re: lustiges problem mit dem compiler (?)
 
Peng. Da fehlt wohl ein static.

sx2008 13. Jun 2009 15:20

Re: lustiges problem mit dem compiler (?)
 
Zitat:

Zitat von Apollonius
Peng. Da fehlt wohl ein static.

"static" :gruebel:
Die Compare-Methode ist doch eine Klassenfunktion (class function).
In C++ oder C# würde man das Schlüsselwort "static" benützen...

Apollonius 13. Jun 2009 15:21

Re: lustiges problem mit dem compiler (?)
 
Versuch's einfach mal. Ohne static wird es nicht funktionieren.

sx2008 13. Jun 2009 15:25

Re: lustiges problem mit dem compiler (?)
 
Zitat:

Zitat von Apollonius
Versuch's einfach mal. Ohne static wird es nicht funktionieren.

"Static" ist aber kein Delphi Schlüsselwort.
Der Compiler kann damit nichts anfangen.

mkinzler 13. Jun 2009 15:28

Re: lustiges problem mit dem compiler (?)
 
Ist auch standard bei delphi
Zitat:

Zitat von Delphi Hilfe
Statische Methoden
Methoden sind standardmäßig statisch. Beim Aufruf bestimmt der deklarierte Typ (also der Typ zur Compilierzeit) der im Aufruf verwendeten Klassen- bzw. Objektvariablen, welche Implementierung aktiviert wird. Die Draw-Methoden im folgenden Beispiel sind statisch


Apollonius 13. Jun 2009 15:34

Re: lustiges problem mit dem compiler (?)
 
Versucht es einfach mal. Ohne die Direktive static funktioniert es einfach nicht, weil selbst bei (nicht-statischen) Klassenmethoden noch ein Self übergeben wird. Markus, dein Hilfezitat bezieht sich nicht auf Klassenmethoden.

himitsu 13. Jun 2009 15:44

Re: lustiges problem mit dem compiler (?)
 
Zitat:

Zitat von sx2008
"Static" ist aber kein Delphi Schlüsselwort.
Der Compiler kann damit nichts anfangen.

[equote="himi's himXML sagt:"]
Delphi-Quellcode:
TXMLFile = Class
  Class Function GetLibVersion: AnsiString; Static;
[/equote]
oder Hier im Forum suchenclass static
http://www.delphipraxis.net/internal...t=class+static
http://www.delphipraxis.net/internal...t=class+static

Desmulator 13. Jun 2009 17:28

Re: lustiges problem mit dem compiler (?)
 
Zitat:

Zitat von arkon
warum funktioniert "Result := Round(TChVoc(Item1).coeff - TChVoc(Item2).coeff);" aber nicht "if Round(TChVoc(Item1).coeff > TChVoc(Item2).coeff) then" !?!??!?!?

Afaik verlangt ein if-Statement immer einen Boolischen Ausdruck. Round gibt aber einen Integer zurück. In deinem zweiten Fall rundest du den Boolischen Ausdruck der duch > erzeugt wird.
Delphi-Quellcode:
Result := Round(TChVoc(Item1).coeff - TChVoc(Item2).coeff);
Result ist ein Integer. Daher möglich.
Delphi-Quellcode:
if Round( TChVoc(Item1).coeff > TChVoc(Item2).coeff ) then
Das Round klammert den Ausdruck TChVoc(Item1).coeff > TChVoc(Item2).coeff ein. Round gibt einen Integer zurück. If will aber einen boolischen haben. Irgendwie geht das nicht oder ? :wink:

Edit: Du könntest auch auf LongBool casten. 0 wär dann true, alles andere false. ( imho )


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:00 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz