Compilerfehler, Zirkelbezug und Includes

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
4Planes
Beiträge: 37
Registriert: 19.11.2020 17:08

Compilerfehler, Zirkelbezug und Includes

Beitrag von 4Planes »

Hallo!
Gleich vorneweg schon mal vielen Dank für jede Hilfe! Dieses Forum und die Leute hier sind wirklich klasse! :allright:


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?
Benutzeravatar
Kurzer
Beiträge: 1569
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Re: Compilerfehler, Zirkelbezug und Includes

Beitrag von Kurzer »

Hallo 4Planes,

wenn ich das richtig verstanden habe, brauchst du den Befehl "XInclude".
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.
Wenns das nicht ist (und ich dein Problem falsch verstanden habe), dann hilft vermutlich nur eine andere Aufteilung deiner Deklarationen.
Kann ich in Datei A irgendwie den Compiler darauf hinweisen, dass die Liste in Datei B deklariert wird?
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.

Gruß Markus
"Never run a changing system!"
PB 5.73 x64, OS: Windows 7 Pro x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Ich bin Baujahr 1968, also aktuell 53.
YouTube-Kanal: Awamii
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8417
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 20.10
NVIDIA Quadro P2200
Wohnort: Saarbrücken
Kontaktdaten:

Re: Compilerfehler, Zirkelbezug und Includes

Beitrag von NicTheQuick »

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()
Bild
Benutzeravatar
4Planes
Beiträge: 37
Registriert: 19.11.2020 17:08

Re: Compilerfehler, Zirkelbezug und Includes

Beitrag von 4Planes »

Danke für die schnellen Antworten. Noch komme ich aber nicht weiter.

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

---------------------
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.

Kurzer hat geschrieben: Wenns das nicht ist (und ich dein Problem falsch verstanden habe), dann hilft vermutlich nur eine andere Aufteilung deiner Deklarationen.
Gibt es dabei grundsätzlich so was wie eine best practice?
Kurzer hat geschrieben:
Kann ich in Datei A irgendwie den Compiler darauf hinweisen, dass die Liste in Datei B deklariert wird?
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.
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? :mrgreen: :wink:
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6840
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Compilerfehler, Zirkelbezug und Includes

Beitrag von STARGÅTE »

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:

Code: Alles auswählen

Structure Alpha
	List  *Beta.Beta()
EndStructure

Structure Beta
	List  *Alpha.Alpha()
EndStructure
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.
PB 5.73 ― Win 10, 20H2 ― Ryzen 9 3900X ― Radeon RX 5600 XT ITX ― Vivaldi 4.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
man-in-black
Beiträge: 362
Registriert: 21.08.2006 17:39

Re: Compilerfehler, Zirkelbezug und Includes

Beitrag von man-in-black »

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 :/
(hab alles, kann alles, weiß alles!!^^)

Bild
Benutzeravatar
4Planes
Beiträge: 37
Registriert: 19.11.2020 17:08

Re: Compilerfehler, Zirkelbezug und Includes

Beitrag von 4Planes »

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:

/
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.
Vielen Dank! Dann ist das der Weg, den ich gehe.
Antworten