Einzelnen Beitrag anzeigen

Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#11

AW: Warum gibt es hier eine Acess Violation?

  Alt 8. Dez 2018, 10:44
Es ist aber doch auch so, dass dies ein Design-Ratschlag ist und keinerlei technische Nachteile hat? (Delphi lässt ja diese Konstruktion explizit zu!)
Es gibt tatsächlich einen technischen Hintergrund. Die Variablen innerhalb einer Methode werden auf dem Stack angelegt. Der Zugriff erfolgt über einen Offset zum Stackregister. Wird nun innerhalb dieser Methode eine lokale Unterroutine aufgerufen ändert sich aber dieses Stackregister. Wenn nun diese Unterroutine auf Variablen der übergeordneten Methode zugreift, muss der Compiler erstmal den passenden Offset zum aktuellen Stackregister ermitteln. Das kostet Zeit und deshalb sind Zugriffe auf solche übergeordnete Variablen zeitaufwändiger als wenn diese als Var-Parameter an die Unterroutine übergeben werden.

@Uwe Raabe: Könntest du das kurz erläutern?
Na ja, erklärt isch doch eigentlich von selbst: Wenn man eine lokale Unterroutine in eine Klassenmethode umwandeln will, dann kann man eben nicht auf solche übergeordneten Variablen zugreifen. Bleibt also nur die Übergabe als Parameter oder Umwandlung der lokalen Variable in ein Feld der Klasse (wenn man globale Variablen mal ausschließt).

Hier kommt es zu dem geschilderten Phänomen. Die TObjectList ist bei der Klassenmethode deklariert und im Debugger in allen Unterprozeduren sichtbar. Trotzdem kommt es zu einer Schutzverletzung, wenn ich keine globale Variable verwende. Was genau geschieht da?
Der Fehler liegt in der Übergabe einer lokalen Methode (FindeDateiRM) als Prozedurtyp (TFindeDateienRM). Ich kann gar nicht glauben, daß der Compiler das durchgehen lässt. Vermutlich weil hier der @-Operator zum Einsatz kommt und damit die Typsicherheit umgangen wird. Die Deklaration von TFindeDateienRM lässt eigentlich nur eine globale procedure oder eine statische class procedure zu. Andernfalls passt der Stack nicht richtig. Je nachdem, was in der Methode gemacht wird kracht es eben oder kracht es nicht.

Berücksichtigt man nun das oben beschriebene Verhalten beim Zugriff auf die übergeordnete Variable, kommt es zum Crash, weil der Stack beim Aufruf des Callbacks eben nicht so ist, wie es die Unterroutine erwartet.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat