Problem mit Defined

Anfängerfragen zum Programmieren mit PureBasic.
Tanaghra
Beiträge: 28
Registriert: 13.05.2017 01:44

Problem mit Defined

Beitrag von Tanaghra »

Hallo,

ich habe ein Problem mit der Defined-Funktion. Bedauerlicherweise kann ich das Problem nur beschreiben, aber es nicht mit einem Kodestück reproduzieren, weil es nur in meinem kompletten Programm auftritt, nicht aber in scheinbar identischen kürzeren Kodestücken. Aber vielleicht kann mir ja trotzdem jemand helfen.

Also: Ich habe ein Fenster mit diversen Schaltflächen und folgerichtig auch eine Repeat-Until-Schleife, die zu den entsprechenden Cases springt, wenn eine Schaltfläche angeklickt wird. Die Schleife selber arbeitet absolut perfekt, dort liegt also nicht der Fehler. Der Case, in dem der Fehler auftritt, hat folgende Struktur:

Code: Alles auswählen

Case #Bs_Abk ; Abkürzungen
  If Not Defined(Ad, #PB_Variable)
    Define …
    Define …
    Define Ad.s

    Select GetGadgetText(#Lz_S)
      Case "Englisch"
        Ad="Englisch Abkürzungen.txt" ; Abkürzungsdatei
      Case "Russisch"
        Ad="Russisch Abkürzungen.txt"
    EndSelect
    …
    …
  EndIf
	OpenWindow(2, 0, 0, BrAbk+Brag+30, HAf+20, #Empty$,
	  #PB_Window_BorderLess|#PB_Window_WindowCentered, WindowID(0))
  UseGadgetList(WindowID(2))
  TextGadget(#Bz_Abk, 10, 10, BrAbk, HAf, IAbkb)
  TextGadget(#Bz_ag, BrAbk+20, 10, Brag, HAf, IagB)
  Repeat: Until WaitWindowEvent()=#WM_LBUTTONDOWN
  CloseWindow(2)
EndSelect
Der Zweck von

Code: Alles auswählen

If Not Defined(Ad, #PB_Variable)
ist, daß der If-Block nur dann abgearbeitet werden soll, wenn Ad NICHT deklariert ist. D.h., der If-Block soll überhaupt nur ein einziges Mal durchlaufen werden, nämlich beim allerersten Betätigen der Schaltfläche, die den Case #Bs_Abk auslöst. Beim zweiten Anklicken der Schaltfläche soll der If-Block nicht mehr abgearbeitet werden, denn dann sind alle Variablen für den unter dem If-Block folgenden OpenWindow-Befehl definiert, inklusive Ad selbst.

Das Problem besteht nun darin, daß der If-Block auch dann abgearbeitet wird, wenn Ad bereits deklariert ist (also beim zweiten Anklicken der Schaltfläche). Ad hat sogar einen Wert, was mir der Debugger bei der Einzelschrittabarbeitung bestätigt (Ad = "Englisch Abkürzungen.txt"), und trotzdem wird in den If-Block verzweigt, anstatt ihn zu überspringen.

Deklariert man Ad vorher (vor der Select/EndSelect-Struktur) und ändert

Code: Alles auswählen

If Not Defined(Ad, #PB_Variable)
in

Code: Alles auswählen

If Ad=#Empty$
tritt der Fehler nicht auf, d.h. der If-Block wird wie beabsichtigt übersprungen. Denn Ad ist ja jetzt nicht mehr leer.

Hat irgendjemand eine Idee, wieso If Not Defined nicht funktioniert wie geplant?

Vielen Dank
Windows 7 x64; geposteter Kode bezieht sich (sofern nicht anders angegeben) immer auf das aktuellste PureBasic 64-Bit

Erst wenn man es seiner Schwiegermutter erklären kann, hat man es verstanden.
As gsündeste is oiwei guad essn und dringa und ned grang wern.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
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: Problem mit Defined

Beitrag von NicTheQuick »

Das ist einfach zu erklären. Die Funtkion Defined() wird zur Übersetzungszeit ausgewertet und ihr Wert ändert sich danach zur Laufzeit nicht mehr.
Wurde also 'Ad' vor dem Aufruf der Funktion deklariert, dann gibt sie #True zurück, ansonsten #False. Und das ändert sich auch nicht mehr, wenn du 'Ad' danach deklarierst und dann die Schleife wieder von vorne beginnt. So funktioniert Purebasic nicht. So, wie du es machen willst, funktioniert es nur in Skriptsprachen, nicht bei zu Maschinencode kompilierten Programmen.
Bild
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: Problem mit Defined

Beitrag von Nino »

Deshalb ist es m.E. übersichtlicher und besserer Programmierstil, alle Variablendeklarationen wie Define Ad.s und Ähnliches immer am Anfang des Gültigkeitsbereiches der betr. Variablen zu schreiben (also auch z.B. Protected x nur am Anfang einer Prozedur), und nicht irgendwo "mittendrin" im Code. Dann kommt der Leser des Codes (der man ggf. selbst ist) nicht so leicht auf falsche Ideen. :-)
Antworten