Hallo!
Gleich vorneweg schon mal vielen Dank für jede Hilfe! Dieses Forum und die Leute hier sind wirklich klasse!
Ich habe ein einfaches Problem, für das ich selber leider keine einfach Lösung finde (jedenfalls keine, die mir gefällt).
Ich habe den Code meines Programms auf mehrere Dateien aufgeteilt, die ich mit "Include" einbinde. Sortiert habe ich ganz einfach danach, was thematisch zusammengehört. Ich habe z.B. eine Datei, die alle Prozeduren beinhaltet, die sich um die Menüs drehen, eine andere, die alle Prozeduren bzgl. Gamepads/Joysticks beinhaltet usw.
Nun komme ich zum ersten Mal mit dieser Aufteilung nicht weiter, weil ich eine Art Zirkelbezug geschaffen habe. Die Prozeduren in Datei B brauchen die Prozeduren von Datei A. Das ist so weit kein Problem. Ich binde einfach Datei B nach Datei A ein. Aber eine Prozedur aus Datei A braucht den Inhalt einer Liste, die von einer Prozedur in Datei B erstellt wird.
Jetzt habe ich keine Möglichkeit mehr, das Projekt zu kompilieren, weil der Kompiler sich bei Datei A beschwert, dass die Liste nicht deklariert wurde und gar nicht bis zu Datei B weitermacht.
Der Fehler ist für mich nicht so ganz nachvollziehbar. Ja, ich sehe den Zirkelbezug selber, aber schaut man sich den Code an, gibt es absolut keine Möglichkeit, dass die Liste in Datei A benutzt wird, bevor sie in Datei B erstellt und mit Werten versehen wurde. Folgt man der Logik des Codes, gibt es kein Problem. Der Fehler kommt scheinbar daher, dass der Compiler stur von vorne nach hinten den Code abarbeitet.
Ich habe keine Ahnung, was jetzt der beste Weg ist. Vielleicht (Sicher) hätte ein Profi, den Code und das ganze Projekt schon anders aufgebaut… Aber wie gehe ich jetzt damit am besten um?
- Kann ich in Datei A irgendwie den Compiler darauf hinweisen, dass die Liste in Datei B deklariert wird?
- Soll ich die Liste, obwohl sie eigentlich zu Datei B gehört, in Datei A deklarieren? (Löst das Problem, macht den Code aber wieder unübersichtlicher)
- Soll ich gleich alle globalen Variablen, Listen und Arrays in einer gesonderten Datei deklarieren und diese einbinden? (Finde ich auch nicht so übersichtlich)
- Etwas ganz anderes?
Compilerfehler, Zirkelbezug und Includes
Re: Compilerfehler, Zirkelbezug und Includes
Hallo 4Planes,
wenn ich das richtig verstanden habe, brauchst du den Befehl "XInclude".
Gruß Markus
wenn ich das richtig verstanden habe, brauchst du den Befehl "XInclude".
Wenns das nicht ist (und ich dein Problem falsch verstanden habe), dann hilft vermutlich nur eine andere Aufteilung deiner Deklarationen.Hilfe hat geschrieben hat geschrieben:IncludeFile fügt die genannte Programmdatei (Datei mit PureBasic-Sourcecode) an der aktuellen Stelle in den Programmcode ein.
XIncludeFile macht genau dasselbe, außer dass es vermeidet, dieselbe Datei mehrfach einzufügen.
Da es sich um einen 1 pass Compiler handelt, geht das leider nicht. Alles was du benutzt, muss vorher in der Sourcedatei schon deklariert worden sein. Aber wie gesagt, evtl. kommst du mit XInclude bei der Aufteilung schon weiter.Kann ich in Datei A irgendwie den Compiler darauf hinweisen, dass die Liste in Datei B deklariert wird?
Gruß Markus
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
- NicTheQuick
- Ein Admin
- Beiträge: 8679
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
- Kontaktdaten:
Re: Compilerfehler, Zirkelbezug und Includes
Procedures kannst du im Voraus deklarieren, noch bevor sie definiert wurden, falls dir das hilft:
Code: Alles auswählen
; Deklaration
Declare.i A()
Procedure B()
A()
EndProcedure
; Definition
Procedure A()
Debug "Hi"
EndProcedure
B()
Re: Compilerfehler, Zirkelbezug und Includes
Danke für die schnellen Antworten. Noch komme ich aber nicht weiter.
Hier ein Skizze des Problems
Das Problem in dieser Skizze ist Prozedur drei() in Datei A. Die Prozedur ist auf eine Liste angewiesen, die in Datei B erstellt wird.
XInclude hilft hier nichts. Würde ich am Anfang von Datei A XInclude "Datei B" schreiben, würde der Compiler sich beschweren, dass die Prozeduren aus Datei A fehlen.
Declare hilft hier auch nichts. Das Problem meiner Skizze oben würde es zusammen mit XInclude lösen, aber das zieht wieder einen eigenen Rattenschwanz an Schwierigkeiten nach sich.
Hier ein Skizze des Problems
Code: Alles auswählen
---- Datei Main.pb ----
Include "Datei A.pb"
Include "Datei B.pb"
vier()
fünf()
sechs()
---------------------
---- Datei A.pb ----
Procedure eins()
…
EndProcedure
Procedure zwei()
…
EndProcedure
Procedure drei()
Shared Liste()
ForEach Liste()
…
Next
EndProcedure
---------------------
---- Datei B.pb ----
NewList Liste()
Procedure vier()
eins()
EndProcedure
Procedure fünf()
AddElement ( Liste() )
EndProcedure
Procedure sechs()
drei()
EndProcedure
---------------------
XInclude hilft hier nichts. Würde ich am Anfang von Datei A XInclude "Datei B" schreiben, würde der Compiler sich beschweren, dass die Prozeduren aus Datei A fehlen.
Declare hilft hier auch nichts. Das Problem meiner Skizze oben würde es zusammen mit XInclude lösen, aber das zieht wieder einen eigenen Rattenschwanz an Schwierigkeiten nach sich.
Gibt es dabei grundsätzlich so was wie eine best practice?Kurzer hat geschrieben: Wenns das nicht ist (und ich dein Problem falsch verstanden habe), dann hilft vermutlich nur eine andere Aufteilung deiner Deklarationen.
Ich habe jetzt mal ein bisschen nachgelesen, wie ein 1 pass Compiler funktioniert und kann jetzt immerhin verstehen, warum der Compiler hier überhaupt protestiert. Ein multi-pass compiler würde mein Problen lösen. Hat zufällig jemand einen programmiert?Kurzer hat geschrieben:Da es sich um einen 1 pass Compiler handelt, geht das leider nicht. Alles was du benutzt, muss vorher in der Sourcedatei schon deklariert worden sein.Kann ich in Datei A irgendwie den Compiler darauf hinweisen, dass die Liste in Datei B deklariert wird?
Re: Compilerfehler, Zirkelbezug und Includes
Im Zusammenhang mit Pure Basic habe ich mir angewöhnt, bei großen Projekten alle Deklarationen und die Funktionen selbst zu trennen. So habe ich Include-Dateien (Header-Dateien) die ausschließlich Konstanten, Strukturen und Deklarationen enthalten und Include-Dateien die die ganzen Prozeduren haben.
Im Projekt kann ich kann "einfach" zuerst alle Header-Dateien per IncludeFile einladen und danach alle "richtigen" Includes.
Das ist eine Lösung für alle Funktionsaufrufe, aber natürlich gibt es auch dann noch Probleme, wenn sich zwei Strukturen in keine Reihenfolge bringen lassen, Beispiel:
Dies wäre eigentlich eine "erlaubte" Strukturzuweisung. Es gibt zwar den Zirkulären bezug, aber da die Element ja nicht sofort erstellt werden (w.z.B. bei einem Array) wäre es nutzbar. Hier Hilft es leider nur Fake-Strukturen zu nutzen und dem Pointer eine andere Struktur zuzuweisen, auf die er eigentlich verweist.
Im Projekt kann ich kann "einfach" zuerst alle Header-Dateien per IncludeFile einladen und danach alle "richtigen" Includes.
Das ist eine Lösung für alle Funktionsaufrufe, aber natürlich gibt es auch dann noch Probleme, wenn sich zwei Strukturen in keine Reihenfolge bringen lassen, Beispiel:
Code: Alles auswählen
Structure Alpha
List *Beta.Beta()
EndStructure
Structure Beta
List *Alpha.Alpha()
EndStructure
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
- man-in-black
- Beiträge: 362
- Registriert: 21.08.2006 17:39
Re: Compilerfehler, Zirkelbezug und Includes
Hi,
ich löse obiges Problem, indem ich quasi eine header-Datei erstelle:
Eine Datei beinhaltet die Proceduren und die zweite alle Strukturen, Konstanten und eben die Declares zu den Proceduren.
In einer weiteren zentralen Datei lade ich dann alle includes nach, wobei im ersten Block die header und im zweiten erst die Dateien mit den Proceduren eingebunden werden:
MFG
MIB
Edit: zu langsam :/
ich löse obiges Problem, indem ich quasi eine header-Datei erstelle:
Eine Datei beinhaltet die Proceduren und die zweite alle Strukturen, Konstanten und eben die Declares zu den Proceduren.
In einer weiteren zentralen Datei lade ich dann alle includes nach, wobei im ersten Block die header und im zweiten erst die Dateien mit den Proceduren eingebunden werden:
MFG
MIB
Edit: zu langsam :/
Re: Compilerfehler, Zirkelbezug und Includes
man-in-black hat geschrieben:Hi,
ich löse obiges Problem, indem ich quasi eine header-Datei erstelle:
Eine Datei beinhaltet die Proceduren und die zweite alle Strukturen, Konstanten und eben die Declares zu den Proceduren.
In einer weiteren zentralen Datei lade ich dann alle includes nach, wobei im ersten Block die header und im zweiten erst die Dateien mit den Proceduren eingebunden werden:
/
Vielen Dank! Dann ist das der Weg, den ich gehe.STARGÅTE hat geschrieben:Im Zusammenhang mit Pure Basic habe ich mir angewöhnt, bei großen Projekten alle Deklarationen und die Funktionen selbst zu trennen. So habe ich Include-Dateien (Header-Dateien) die ausschließlich Konstanten, Strukturen und Deklarationen enthalten und Include-Dateien die die ganzen Prozeduren haben.
Im Projekt kann ich kann "einfach" zuerst alle Header-Dateien per IncludeFile einladen und danach alle "richtigen" Includes.