Ärger mit der Sichtbarkeit(?) in Turbo-Pascal Objekten
Ärger mit der Sichtbarkeit(?) in Turbo-Pascal Objekten
Hallo zusammen,
ich bin ein wenig ratlos wegen eines Fehlers in einem Programm, den ich ehrlich gesagt so nicht verstehe. Ich gebe zu, ich habe zwar ein wenig mit Objekten in Lazarus und anderen Programmiersprachen gearbeitet, aber nicht in Turbo-Pascal. Dummerweise soll mein Programm da aber laufen - ich habe jetzt wochenlang geübt in Python und in Java, die Ursprungsquelle war weder oo noch schick strukturiert sondern einfach dBaseIV.
Jetzt habe ich schicke Lösungen in Python und auch in Java und auch mein Lazarus-Programm läuft an sich, wenn es mir auch vergleichsweise umständlich formuliert vorkommt, aber egal es läuft. Mein Clone in Turbo-Pascal ($DEFINE DOS} tut es aber nicht wegen einem Syntaxfehler bei der Benutzung meiner (Array-)Liste Unit. Speziell wird ein nicht sichtbares Feld "Head" angemeckert, was ein Pointer der Liste sein sollte. Allerdings habe ich es soweit ich beurteilen kann, schon public und auch ein Getter oder First und Next Methoden haben alles nicht geholfen, letztere will ich auch gar nicht weil die ArrayList im generischen Fall so schon gut ist. Lazararus-Collections könnte ich nehmen, aber der Fehler tritt ja im DOS-Pfad auf.
Könnte bitte jemand so lieb sein und mal meine Quelle(n) anschauen, was ich da verbockt habe? Wie gesagt das Programm wäre mir gerade für den DOS-Fall wichtig, in den anderen (Python, Java, Lazarus) geht es ja schon.
ich bin ein wenig ratlos wegen eines Fehlers in einem Programm, den ich ehrlich gesagt so nicht verstehe. Ich gebe zu, ich habe zwar ein wenig mit Objekten in Lazarus und anderen Programmiersprachen gearbeitet, aber nicht in Turbo-Pascal. Dummerweise soll mein Programm da aber laufen - ich habe jetzt wochenlang geübt in Python und in Java, die Ursprungsquelle war weder oo noch schick strukturiert sondern einfach dBaseIV.
Jetzt habe ich schicke Lösungen in Python und auch in Java und auch mein Lazarus-Programm läuft an sich, wenn es mir auch vergleichsweise umständlich formuliert vorkommt, aber egal es läuft. Mein Clone in Turbo-Pascal ($DEFINE DOS} tut es aber nicht wegen einem Syntaxfehler bei der Benutzung meiner (Array-)Liste Unit. Speziell wird ein nicht sichtbares Feld "Head" angemeckert, was ein Pointer der Liste sein sollte. Allerdings habe ich es soweit ich beurteilen kann, schon public und auch ein Getter oder First und Next Methoden haben alles nicht geholfen, letztere will ich auch gar nicht weil die ArrayList im generischen Fall so schon gut ist. Lazararus-Collections könnte ich nehmen, aber der Fehler tritt ja im DOS-Pfad auf.
Könnte bitte jemand so lieb sein und mal meine Quelle(n) anschauen, was ich da verbockt habe? Wie gesagt das Programm wäre mir gerade für den DOS-Fall wichtig, in den anderen (Python, Java, Lazarus) geht es ja schon.
- Dateianhänge
-
freiburg.zip
- (75.93 KiB) 93-mal heruntergeladen
-
- Beiträge: 6919
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Ärger mit der Sichtbarkeit(?) in Turbo-Pascal Objekten
Kannst du uns zeigen, wo der Syntaxfehler ist, Datei / Zeile.
Oder noch besser, das was der Compiler ausspuckt.
Oder noch besser, das was der Compiler ausspuckt.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
Re: Ärger mit der Sichtbarkeit(?) in Turbo-Pascal Objekten
Also Turbo-Pascal bemängelt in FREIBURG.PAS, Zeile 61, Spalte 21 das .Head aus der Anweisung
zeiger := gesamt.head;
Fehler 44, Feldbezeichner erwartet. Ich nehme an, die weiteren Stellen zB Zeilen 76, 89, 96 und 106 wo ich in ähnlicher Weise den Kopf meiner Liste haben will, wird nach dem 1.Compilerfehler abgebrochen. Lazarus hat keinen Fehler, da ist ja auch $ELSE vom $IFDEF DOS also zieht er eine andere Definition aus der
LISTE.PAS wo ich eigentlich gehofft hatte daß mein "Head" in Zeile 20 zu sehen ist. Habe schon alles probiert, public, getter, first/next-Methoden, anscheinend ist nichts sichtbar
Oder ich habe Tomaten auf den Augen
Vielleicht habe ich den TMListe oder TMEintrag für DOS falsch definiert, aber dann sollte eine andere Fehlermeldung kommen und nicht "Feldbezeichner erwartet"?
zeiger := gesamt.head;
Fehler 44, Feldbezeichner erwartet. Ich nehme an, die weiteren Stellen zB Zeilen 76, 89, 96 und 106 wo ich in ähnlicher Weise den Kopf meiner Liste haben will, wird nach dem 1.Compilerfehler abgebrochen. Lazarus hat keinen Fehler, da ist ja auch $ELSE vom $IFDEF DOS also zieht er eine andere Definition aus der
LISTE.PAS wo ich eigentlich gehofft hatte daß mein "Head" in Zeile 20 zu sehen ist. Habe schon alles probiert, public, getter, first/next-Methoden, anscheinend ist nichts sichtbar

Oder ich habe Tomaten auf den Augen
Vielleicht habe ich den TMListe oder TMEintrag für DOS falsch definiert, aber dann sollte eine andere Fehlermeldung kommen und nicht "Feldbezeichner erwartet"?
- kupferstecher
- Beiträge: 434
- Registriert: Do 17. Nov 2016, 11:52
Re: Ärger mit der Sichtbarkeit(?) in Turbo-Pascal Objekten
Habs mir kurz angeschaut, .Head zeigt doch auf einen anderen Typ, nämlich auf
Zeiger zeigt auf TEintrag
Edit: WIe ist das in Turbopascal, werden da Pointer auf Feder automatisch dereferenziert? Dann könnten sich die Kompilerentwickler gedacht haben dass der Standardfall ist, dass man nur das Feld vergessen hat, das dann den passenden Typen hat.
Code: Alles auswählen
TListeElement = RECORD
Data: Pointer;
Next: PListeElement;
END;
Code: Alles auswählen
TEintrag = RECORD
M1, M2, M3, N1, N2, L1: INTEGER;
PROG, BEZEICHNER, CODE: STRING[50];
END;
Re: Ärger mit der Sichtbarkeit(?) in Turbo-Pascal Objekten
Ja du hast recht, meine Sammeldeklaration TMEintrag ist für den $DEFINE DOS Fall falsch und muß auf PListeElement lauten. Das habe ich gestern noch korrigiert (ich hatte die ganze Zeit vorher in Lazarus entwickelt und da fiel es nicht auf), mir dann aber neue Probleme geholt. Mittlerweile löuft der Quelltext in Turbo wieder, nachdem ich eine Zwischenvariable eingeführt habe. Das muß ich aber noch verifizieren (anscheinend eine "Grenze" des Turbo Compilers) und leider haut es mir auch meine bedingte Compilierung durcheinander bzw das wird unansehnlich. Ich versuche es noch mal und zeige dann das Ergebnis.kupferstecher hat geschrieben: Mo 4. Nov 2024, 20:59 Habs mir kurz angeschaut, .Head zeigt doch auf einen anderen Typ, nämlich auf
Zeiger zeigt auf TEintragCode: Alles auswählen
TListeElement = RECORD Data: Pointer; Next: PListeElement; END;
Edit: WIe ist das in Turbopascal, werden da Pointer auf Feder automatisch dereferenziert? Dann könnten sich die Kompilerentwickler gedacht haben dass der Standardfall ist, dass man nur das Feld vergessen hat, das dann den passenden Typen hat.Code: Alles auswählen
TEintrag = RECORD M1, M2, M3, N1, N2, L1: INTEGER; PROG, BEZEICHNER, CODE: STRING[50]; END;
Re: Ärger mit der Sichtbarkeit(?) in Turbo-Pascal Objekten
Also das Rätsel ist gelöst. Ich hatte einen Denkfehler in einer (zusätzlichen) Typvereinbarung, die ich eingeführt hatte um mir das oftmalige bedingte Compilieren zu sparen.
Als ich das für den (bisher ungetesteten) MSDOS/Turbo-Pascal Fall korrigiert habe, stand ich zwar vor einem neuen Problem, denn meine Stack/ArrayList-Units arbeiten für DOS mit Pointer und für Lazarus mit Generics
Daran mußte mich der Compiler erst schmerzhaft erinnern (ich kann nicht einfach den Ergebnis-Record so abfragen sondern muß erst den Pointer auflösen im DOS-Fall), schade nun habe ich das so oft gemacht mit der $IFDEF DOS Unterscheidung und wenn es darauf ankommt denkt man nicht daran. Leider mag der Turbo Pascal auch keine doppelten ^ also was ich meine habe ich hier mal im Testcode:
Man sieht im Murphy-Fall kommt wirklich alles zusammen.
Die richtige, und jetzt in Lazarus wie in Turbo-Pascal laufende Methode sieht nun so aus:
Es war also nur scheinbar die "Sichtbarkeit" sondern ein anderes kleines Problemchen, welches mir der Turbo-Pascal Compiler nicht abgenommen hat, weil ich nicht exakt genug war.
HIer kommt noch meine Bitte. Ich hänge noch einmal das komplette richtige Programm in den Thread (nehme dafür oben raus mit dem Fehler?) und frage um Feedback und vernichtende Kritik zum Quelltext des Hauptprogramms freiburg.pas und den beiden Units Stack und Liste. Ich weiß schon - es ist vermutlich umständlicher als mit den schicken Lazarus-Bibliotheken ausgedrückt und noch viel viel umständlicher als in Java oder gar Python. Auch mußte ich Rücksicht nehmen auf Turbo-Pascal und generell habe ich mal auf VAR Ergebnisparameter gesetzt, weil komplexere Funktionsergebnisse nicht so meins und Turbos Ding sind.
Aber habt ihr generell Verbesserungsvorschläge? Im Java und im Python Programm habe ich nachträglich Programmkonstrukte eingebaut, auf die ich nie im Leben selber gekommen wäre, die einem das Leben aber leichter machen können
Als ich das für den (bisher ungetesteten) MSDOS/Turbo-Pascal Fall korrigiert habe, stand ich zwar vor einem neuen Problem, denn meine Stack/ArrayList-Units arbeiten für DOS mit Pointer und für Lazarus mit Generics
Code: Alles auswählen
UNIT Liste;
{$I OsWahl.inc}
{$IFNDEF DOS} {$MODE OBJFPC} {$H+} {$ENDIF}
INTERFACE
TYPE
{$IFDEF DOS}
PListeElement = ^TListeElement;
TListeElement = RECORD
Data: Pointer;
Next: PListeElement;
END;
TListe = OBJECT
Public
Head, Tail: PListeElement;
DataSize: Integer;
Count: Integer;
{$ELSE}
GENERIC TListe<T> = OBJECT
Private
TYPE
PListeElement = ^TListeElement;
TListeElement = RECORD
Data: T;
Next: PListeElement;
END;
VAR
Head, Tail: PListeElement;
Count: Integer;
{$ENDIF}
Public
PROCEDURE Init {$IFDEF DOS} (SizeOfData: Integer) {$ENDIF} ;
PROCEDURE Add(Data: {$IFDEF DOS} Pointer {$ELSE} T {$ENDIF});
FUNCTION Get(Index: Integer; {$IFDEF DOS} Data: Pointer {$ELSE} VAR Data: T {$ENDIF}): BOOLEAN;
FUNCTION Remove(Index: Integer): BOOLEAN;
FUNCTION IsEmpty: BOOLEAN;
PROCEDURE Clear;
FUNCTION Anzahl: Integer;
FUNCTION Start: PListeElement;
END;
Code: Alles auswählen
FUNCTION TMenueManager.Aktuelle_Menuepunkte_Test(VAR Ergebnis: TMListe): BOOLEAN;
VAR Zeiger: PMEintrag; (* Pointer *)
RecTemp: TEintrag; (* Record *)
PointTemp: PEintrag; (* Pointer *)
BEGIN
Ergebnis.Clear;
Zeiger := Gesamt.Head;
WHILE Zeiger <> NIL DO BEGIN
PointTemp := Zeiger^.Data;
IF (PointTemp^.M1 = aktuell.M1) AND (PointTemp^.M2 = aktuell.M2) THEN
Ergebnis.Add(PointTemp);
RecTemp := PointTemp^;
IF (RecTemp.M1 = aktuell.M1) AND (RecTemp.M2 = aktuell.M2) THEN
Ergebnis.Add(Zeiger^.Data);
(* direkt ohne Zwischenvariable, 2x ^ geht nicht *)
(*RecTemp := Zeiger^.Data^; *)
(* direkt ohne Zwischenvariable, mit Klammern, geht auch nicht *)
(* RecTemp := (Zeiger^).Data^; *)
(* direkt ohne Zwischenvariable, mit Klammern, geht auch nicht *)
(* RecTemp := (Zeiger^.Data)^; *)
IF (PointTemp^.M1 = aktuell.M1) AND (PointTemp^.M2 = aktuell.M2) THEN
Ergebnis.Add(Zeiger^.Data);
(* direkt wie in Lazarus geht nicht weil in Turbo Nutzdaten Pointer
und in Lazarus Data = TEintrag *)
(* IF (Zeiger^.Data.M1 = aktuell.M1) AND (Zeiger^.Data.M2 = aktuell.M2) THEN
Ergebnis.Add(Zeiger^.Data);
*)
Zeiger := Zeiger^.Next;
END;
Die richtige, und jetzt in Lazarus wie in Turbo-Pascal laufende Methode sieht nun so aus:
Code: Alles auswählen
PROCEDURE TMenueManager.Inhalt(Zeiger: PMEintrag; VAR Eintrag: TEintrag);
{$IFDEF DOS} VAR Temp: PEintrag; {$ENDIF}
BEGIN
{$IFDEF DOS} Temp := Zeiger^.Data; Eintrag := Temp^; {$ELSE} Eintrag := Zeiger^.Data; {$ENDIF}
END;
FUNCTION TMenueManager.Aktuelle_Menuepunkte(VAR Ergebnis: TMListe): BOOLEAN;
VAR Zeiger: PMEintrag;
Eintrag: TEintrag;
BEGIN
Ergebnis.Clear;
Zeiger := Gesamt.Head;
WHILE Zeiger <> NIL DO BEGIN
Inhalt(Zeiger, Eintrag);
IF (Eintrag.M1 = aktuell.M1) AND (Eintrag.M2 = aktuell.M2)
THEN Ergebnis.Add({$IFDEF DOS}@{$ENDIF}Eintrag);
Zeiger := Zeiger^.Next;
END;
Aktuelle_Menuepunkte := Ergebnis.Anzahl <> 0;
END;
HIer kommt noch meine Bitte. Ich hänge noch einmal das komplette richtige Programm in den Thread (nehme dafür oben raus mit dem Fehler?) und frage um Feedback und vernichtende Kritik zum Quelltext des Hauptprogramms freiburg.pas und den beiden Units Stack und Liste. Ich weiß schon - es ist vermutlich umständlicher als mit den schicken Lazarus-Bibliotheken ausgedrückt und noch viel viel umständlicher als in Java oder gar Python. Auch mußte ich Rücksicht nehmen auf Turbo-Pascal und generell habe ich mal auf VAR Ergebnisparameter gesetzt, weil komplexere Funktionsergebnisse nicht so meins und Turbos Ding sind.
Aber habt ihr generell Verbesserungsvorschläge? Im Java und im Python Programm habe ich nachträglich Programmkonstrukte eingebaut, auf die ich nie im Leben selber gekommen wäre, die einem das Leben aber leichter machen können
- Dateianhänge
-
freiburg.zip
- (76.37 KiB) 78-mal heruntergeladen