| Autor |
Beitrag |
alias5000
      
Beiträge: 2145
WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
|
Verfasst: Di 25.09.07 20:15
Hi!
Ich bin grad beim Umschreiben einer größeren Klasse auf das klassische Problem gestoßen, dass ich eine überkreuzte Benutzung im Interface Teil produziere (in etwa sowas, wie z.B. hier: www.delphi-forum.de/...hlight=%DCberkreu%2A). Die Änderungen, die ich jetzt an meiner Klasse gemacht habe, kann ich jetzt wieder rückgängig machen, weil eine Ausweichlösung gegenüber der alten Lösung keine wirklichen Vorteile bietet.
Mich würde interessieren, warum es in Delphi nicht möglich ist, einen überkreuzenden Bezug im Interface Teil zu produzieren (nochmal simples Beispiel unten, zur Visualisierung  ). Welchen Grund hat das, ist der historischer oder technischer Art, oder ist das einfach Design?
(ich sehe in dieser Beschränkung) im Moment keinen Vorteil, außer ich übersehe etwas
Hier zum Bleistift:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| interface
type
TClassA = class variable: TClassB; end;
TClassB = class variable: TClassA; end; |
Viele Grüße
alias5000
Moderiert von jasocul: Link-Tags gesetzt
_________________ Programmers never die, they just GOSUB without RETURN
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: Di 25.09.07 20:19
Versuchs mal mit einer forward-Deklarartion
_________________ Markus Kinzler.
|
|
Tilman
      
Beiträge: 1405
Erhaltene Danke: 51
Win 7, Android
Turbo Delphi, Eclipse
|
Verfasst: Di 25.09.07 22:24
-- doch net sry
_________________ Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: Di 25.09.07 22:26
@Tilman: das ist eine forward-(Klassen-)Deklaration
_________________ Markus Kinzler.
|
|
Tilman
      
Beiträge: 1405
Erhaltene Danke: 51
Win 7, Android
Turbo Delphi, Eclipse
|
Verfasst: Di 25.09.07 22:34
Ich war mir momentan nicht sicher ob das überhaupt so richtig war, poste du doch mal wie man's genau macht 
_________________ Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 25.09.07 23:07
|
|
Klabautermann
      

Beiträge: 6366
Erhaltene Danke: 60
Windows 7, Ubuntu
Delphi 7 Prof.
|
Verfasst: Di 25.09.07 23:31
Hi,
damals in meiner Ausbildung wurde das auf Turbo Pascal bezogen (mit funktionen und proceduren anstelle von Objekten) damit begründet, dass der Compiler die Datei ansonsten noch ein weiteres mal "vorparsen" müsste. Also erst einmal die ganze unit parsen um alle (globalen)Variablen, Funktionen und Klassen kennen zu können und erst dann das Eigentlich parsing bei welchen diese dann verwendet werden beginnen kann. Es währe also ein nicht unaufwändiger arbeitsschrit mehr und würde damit das Kompilieren langsamer machen. Da es nicht so häufig vorkommt (wenn dann meist bei verketteten Listen und da haben die meisten Leute das deklartionschema eh im Kopf oder im Lehrbuch) spart man sich lieber den Arbeitsschrit und erlaubt dafür die von jaenicke gezeigten forward deklarationen.
Gruß
Klabautermann
|
|
Reinhard Kern
      
Beiträge: 591
Erhaltene Danke: 14
|
Verfasst: Mi 26.09.07 09:12
Klabautermann hat folgendes geschrieben: | Hi,
damals in meiner Ausbildung wurde das auf Turbo Pascal bezogen (mit funktionen und proceduren anstelle von Objekten) damit begründet, dass der Compiler die Datei ansonsten noch ein weiteres mal "vorparsen" müsste.
...
Gruß
Klabautermann |
Hallo,
ich weiss nicht, wie lange deine Ausbildung her ist, aber die Idee des 1 Pass-Compilers hat sich offenbar in den Köpfen der Borland-Programmierer unwiderruflich festgefressen, obwohl es viele Nachteile gibt: Turbo Pascal war immer bekannt dafür, sehr schnell zu übersetzen, dafür aber beim ersten Fehler abzubrechen. Unter DOS hatte ich als Alternative einen Pascal-3-Pass-Compiler von Prospero, da zeigte sich der Unterschied ganz deutlich: mit TP compilieren, Fehler 1 beheben, compilieren, Fehler 2 beheben usw. Bei Propascal liess ich den Compiler laufen und beseitigte nach den Meldungen die meisten Fehler gleich nach dem ersten Durchlauf. Damit war der Geschwindigkeitsvorteil von TP futsch.
Borland/Codegear hat inzwischen viele Energien daran verschleudert, den Compiler in einem Durchlauf möglichst weit kommen zu lassen, hat aber den Schritt zu mehr als einem Pass gescheut. Das hat leider auch andere gravierende Nachteile, z.B. dass in mehreren Units definierte Konstante und Variablen überhaupt nicht erkannt werden, so dass im Mapfile Publics mehrfach auftauchen - da ist Delphi die einzige mir bekannte Sprache, das kann jeder 2-Pass-Assembler besser.
Damit leiden wir an einem Erbe, das aus den Zeiten der CP/M-Diskettensysteme stammt. Auf heutiger Hardware würde ein 2. Durchlauf überhaupt nicht auffallen.
Gruss Reinhard
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 26.09.07 12:28
Reinhard Kern hat folgendes geschrieben: | | Unter DOS hatte ich als Alternative einen Pascal-3-Pass-Compiler von Prospero, da zeigte sich der Unterschied ganz deutlich: mit TP compilieren, Fehler 1 beheben, compilieren, Fehler 2 beheben usw. Bei Propascal liess ich den Compiler laufen und beseitigte nach den Meldungen die meisten Fehler gleich nach dem ersten Durchlauf. Damit war der Geschwindigkeitsvorteil von TP futsch. |
Soo viele Fehler habe ich eigentlich nie in meinem Quelltext, dass sich das lohnen würde. Normalerweise habe ich vielleicht maximal 3-4 Fehler, wenn ich 500 Zeilen oder so blind programmiert habe. Schließlich werden die meisten Fehler ja auch schon beim Schreiben des Quelltextes markiert.
Vor allem sehe ich nicht, wie man unterscheiden soll zwischen Folgefehlern und tatsächlichen Fehlern, die behoben werden müssen (da weiß ich ja nicht, wie das bei Propascal ging). Klar sieht man die meisten echten Fehler eh gleich, wenn man die Fehlerliste durchgeht, aber es macht finde ich viel mehr Mühe als einfach sequentiell die wenigen Fehler, die man gemacht hat, zu beheben. Bei Delphi werden ja auch noch mehr Fehler nach dem ersten angezeigt, aber ich behebe eh erst den ersten und kompiliere neu, einfach um nicht an Folgefehlern zu rätseln (eben weil da ja eigentlich gar kein Fehler ist).
Und wer noch nicht so lange mit Delphi arbeitet und viele Fehler macht, der wird ohnehin nicht gleich alle Fehler beheben wollen, weil er ja vermutlich erstmal prüfen wird, ob die Korrektur des ersten Fehlers stimmte.
Was die Compilierzeit angeht: Die ist schon jetzt bei einem Projekt 31 Sekunden und bei nem anderen 25 Sekunden (auf nem 5000er X2...), da möchte ich nicht wissen, wie das mit nem Multipass-Compiler wäre...
Insofern sehe ich da gar nicht so viele Vorteile gegenüber einem Singlepass-Compiler, und die nötigen Forward-Deklarationen machen ja auch nicht so viel Mühe.
|
|
alias5000 
      
Beiträge: 2145
WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
|
Verfasst: Mi 26.09.07 19:42
Hallo!
Ich finde die aktuelle Diskussion bzgl. den Compilern recht interessant.
Das, was Jaenicke vorgeschlagen hat, bezeichnet man als Forward-Deklaration, wenn ich das richtig rausgehört habe?
Vielen herzlichen Dank für diesen Tipp!
Ich werde das jetzt mal versuchen so umzusetzen. Ich nehme an, dass sich damit meine Frage erledigt hat.
Gruß
alias5000
_________________ Programmers never die, they just GOSUB without RETURN
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Mi 26.09.07 20:12
Reinhard Kern hat folgendes geschrieben: |
Borland/Codegear hat inzwischen viele Energien daran verschleudert, den Compiler in einem Durchlauf möglichst weit kommen zu lassen, hat aber den Schritt zu mehr als einem Pass gescheut. |
Entschuldige, aber das ist so nicht korrekt. Die Fehler vom 'Compiler' schmeisst der Parser aus, und nicht ein n-Pass Compiler. Die Sprache definiert, ob ein nicht deklarierter Bezeichner bei der Verwendung ein Fehler ist, oder nicht.
Delphi / Objekt Pascal erlaubt einfach per definitionem keine Verwendung von Bezeichnern VOR deren Deklaration. Historisch dürfte das im 1-Pass-Compiler verwurzelt sein, das so ein Programm immer 'häppchenweise' übersetzt wird, um Speicher zu sparen. Es hat auch mit der Typensicherheit und den festen Parameterlisten von Prozeduren zu tun, die z.B. bei C nicht gegeben sind.
Früher wurden mehrere Durchläufe (Pass) benötigt, um den Quellcode zu parsen, zu compilieren und zu optimieren. Heutzutage reicht imho ein Durchlauf aus, um das zu bewerkstelligen. C z.B. war früher ein klassisches 2-Pass-Compiler (1.parsen + Macros übersetzen, 2.Codegenerierung).
Das Wiederaufsetzen des Parsers nach einem Syntaxfehler an der richtigen Stelle ist nicht einfach, und manchmal unmöglich. Aus diesem Grund bricht ein Compiler manchmal einfach ab, eben weil er nicht herausbekommen kann, was logisch als nächstes folgen müsste.
Die einfachsten Compiler in der Steinzeit der Computer brachen beim ersten Syntaxfehler einfach ab. Damals war die Forschung einfach noch nicht so weit. Ich habe jedoch schon Anfang der 80er Jahre mit UCSD-Pascal-Compilern gearbeitet, die eigentlich alle Fehler moniert haben. Insofern ist es wohl kein Verdienst der Codegear/Borland-Typen, den Compiler hier verbessert zu haben. Auch kann ich mich nicht erinnern, das sich Delphi 3 bei Fehlern verschluckt hat. Oder ich hab einfach nicht so viele gemacht, kann auch sein.
_________________ Na denn, dann. Bis dann, denn.
|
|
|