Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Zugriff auf andere Konstante als im Source Code angegeben (https://www.delphipraxis.net/190345-zugriff-auf-andere-konstante-als-im-source-code-angegeben.html)

Amateurprofi 26. Sep 2016 11:07

Zugriff auf andere Konstante als im Source Code angegeben
 
Ich hatte gestern ein sehr merkwürdiges Erlebnis.

Szenario:

In einer Unit "Base.pas" sind Typen und Konstanten, die ich in meinem Projekt verwende, deklariert.

In anderen Units greife ich auf diese Daten zu.

In Base.pas standen u.A. folgende Konstanten

Code:
const
   MinTone=21;
   MaxTone=108;
   PianoKeyName:Array[MinTone..MaxTone] of String=
      ('A0','Ais0/B0','H0',
       'C1','Cis1/Des1','D1','Dis1/Es1','E1','F1','Fis1/Ges1','G1','Gis1/As1','A1','Ais1/B1','H1',
       'C2','Cis2/Des2','D2','Dis2/Es2','E2','F2','Fis2/Ges2','G2','Gis2/As2','A2','Ais2/B2','H2',
       'C3','Cis3/Des3','D3','Dis3/Es3','E3','F3','Fis3/Ges3','G3','Gis3/As3','A3','Ais3/B3','H3',
       'C4','Cis4/Des4','D4','Dis4/Es4','E4','F4','Fis4/Ges4','G4','Gis4/As4','A4','Ais4/B4','H4',
       'C5','Cis5/Des5','D5','Dis5/Es5','E5','F5','Fis5/Ges5','G5','Gis5/As5','A5','Ais5/B5','H5',
       'C6','Cis6/Des6','D6','Dis6/Es6','E6','F6','Fis6/Ges6','G6','Gis6/As6','A6','Ais6/B6','H6',
       'C7','Cis7/Des7','D7','Dis7/Es7','E7','F7','Fis7/Ges7','G7','Gis7/As7','A7','Ais7/B7','H7',
       'C8');
Auf "PianoKeyName" wird an verschiedenen Stellen zugegriffen.

Nun wollte ich für eine neue Funktionalität nicht die Texte "Cis1/Des1" etc. verwenden, sondern statt dessen "Cis1".

Also habe ich per Copy/Paste eine Kopie von "PianoKeyName" erstellt und die ursprüngliche Konstante umbenannt in "PianoKeyLongName" .
An den Stellen, an denen auf " PianoKeyName" zugegriffen wurde, habe ich die gleiche Umbenennung vorgenommen.

In "PianoKeyName" habe ich dann mit der Maus mit gedrückter Alt-Taste "/Des1" bis "/Des7" markiert und mit der Delete-Taste entfernt. Das gleiche für die anderen Spalten "/Es11" bist "/B1".

Jetzt hatte ich also folgende Deklarationen:

Code:
   PianoKeyLongName:Array[MinTone..MaxTone] of String=
      ('A0','Ais0/B0','H0',
       'C1','Cis1/Des1','D1','Dis1/Es1','E1','F1','Fis1/Ges1','G1','Gis1/As1','A1','Ais1/B1','H1',
       'C2','Cis2/Des2','D2','Dis2/Es2','E2','F2','Fis2/Ges2','G2','Gis2/As2','A2','Ais2/B2','H2',
       'C3','Cis3/Des3','D3','Dis3/Es3','E3','F3','Fis3/Ges3','G3','Gis3/As3','A3','Ais3/B3','H3',
       'C4','Cis4/Des4','D4','Dis4/Es4','E4','F4','Fis4/Ges4','G4','Gis4/As4','A4','Ais4/B4','H4',
       'C5','Cis5/Des5','D5','Dis5/Es5','E5','F5','Fis5/Ges5','G5','Gis5/As5','A5','Ais5/B5','H5',
       'C6','Cis6/Des6','D6','Dis6/Es6','E6','F6','Fis6/Ges6','G6','Gis6/As6','A6','Ais6/B6','H6',
       'C7','Cis7/Des7','D7','Dis7/Es7','E7','F7','Fis7/Ges7','G7','Gis7/As7','A7','Ais7/B7','H7',
       'C8');

   PianoKeyName:Array[MinTone..MaxTone] of String=
      ('A0','B0','H0',
       'C1','Cis1','D1','Dis1','E1','F1','Fis1','G1','Gis1','A1','Ais1','H1',
       'C2','Cis2','D2','Dis2','E2','F2','Fis2','G2','Gis2','A2','Ais2','H2',
       'C3','Cis3','D3','Dis3','E3','F3','Fis3','G3','Gis3','A3','Ais3','H3',
       'C4','Cis4','D4','Dis4','E4','F4','Fis4','G4','Gis4','A4','Ais4','H4',
       'C5','Cis5','D5','Dis5','E5','F5','Fis5','G5','Gis5','A5','Ais5','H5',
       'C6','Cis6','D6','Dis6','E6','F6','Fis6','G6','Gis6','A6','Ais6','H6',
       'C7','Cis7','D7','Dis7','E7','F7','Fis7','G7','Gis7','A7','Ais7','H7',
       'C8');
In der neu geschriebenen Prozedur, stand dann z.B.
Delphi-Quellcode:
Label1.Caption:=PianoKeyName[25];
Im Label stand dann aber nicht der Text aus "PianoKeyName" sondern der längere Text aus "PianoKeyLongName".
Im DebugMode zeigte Insight, das auf "PianoKeyName" zugegriffen wird, tatsächlich wurde aber auf "PianoKeyLongName" zugegriffen.

Alle Versuche, das zu beheben scheiterten.
Delphi schließen, alle .dcu Dateien löschen Delphi neu starten brachte nichts.
Anderes Projekt laden Delphi schließen, neu starten und dann das Projekt laden, brachte nichts.
Rechner komplett runterfahren brachte nichts.
Die Konstante "PianoKeyName" aus der Unit Base.pas entfernen und in die Unit zu stellen, in der ich darauf zugreifen wollte führte zu einer Exception. (Irgend etwas mit Speicherzugriff).
Auch das Löschen von "PianoKeyLongName" brachte nichts. Es wurde weiterhin auf diese nicht mehr existierende Konstante zugegriffen.

Ich habe dann den gesamten Inhalt aus Base.pas in einen Texteditor kopiert. Base.pas und Base.dcu gelöscht, eine neue Unit erstellt, den Text aus dem Texteditor in die neue Unit kopiert und diese unter Base.pas gespeichert.
Danach funktionierte alles, wie es sollte.

Und nach dieser langen Vorrede die kurzen Fragen:
Woran kann das liegen. (Vermutung: Die Methode wie ich die Texte gelöscht habe)
Wie gehe ich am besten vor, wenn solche Fehler wieder auftreten?

Bjoerk 26. Sep 2016 12:51

AW: Zugriff auf andere Konstante als im Source Code angegeben
 
Das gibts ja gar nicht? :shock: Suchst du mal in den uses units nach nach PianoKeyName. Nenn die neunen ggf. mal um in cPianoKeyName und cPianoKeyLongName.

hoika 26. Sep 2016 14:17

AW: Zugriff auf andere Konstante als im Source Code angegeben
 
Hallo,
benenn sowohl die alte Variable als auch die neue Variable um.
Dann lass den Compiler selber suchen und ändere bei den Abfragen der Variablen
entsprechend die Variablennamen.

mm1256 26. Sep 2016 17:43

AW: Zugriff auf andere Konstante als im Source Code angegeben
 
Heiko :thumb: Genauso mach ich es auch immer. Umbenennen, Projekt neu erzeugen, und dann den Compiler meckern lassen, dann sieht man schon... Übrigens, schönen Gruss an die User der IDE's die sowas nicht unterstützen. Delphi hat manchmal schon seine Vorteile. Aber das nur am Rande.

Als Ursache "vermute" ich irgend ein Cache-Gedöns der IDE. Besonders auffällig war dieses ungewöhnliche Verhalten bei mir immer, wenn die entsprechende Unit nicht explizit in die .DPR eingebunden war, sondern über einen Suchpfad automatisch gefunden wird. Seitdem ich bei eigenen Units generell keine Suchpfade mehr verwende und die Units direkt einbinde, scheint das Problem behoben zu sein.

Namenloser 26. Sep 2016 17:50

AW: Zugriff auf andere Konstante als im Source Code angegeben
 
Zitat:

Zitat von mm1256 (Beitrag 1348866)
IDE's die sowas nicht unterstützen.

Welche wären das?

nahpets 26. Sep 2016 18:00

AW: Zugriff auf andere Konstante als im Source Code angegeben
 
Das Problem hatte ich auch schon mal.

Grund war:

Es gab zu der Unit zwei DCUs, die an unterschiedlichen Stellen abgelegt waren.

Die falsche DCU lag leider im Suchpfad vor der richtigen DCU, so dass IDE und Compiler bei Änderungen irgendwie aneinander "vorbeigeredet" haben.

Irgendwann hab' ich dann für mich entschieden:

Alle DCUs aller Projekte werden an einer Stelle abgelegt. Es gibt nur einen Ausgabepfad für Units.
Wenn irgendein Projekte bei der Entwicklung "rumzickt", wird zuerst dieses Verzeichnis geleert und dann das aktuelle Projekt neu erstellt.

Seit dem hab' ich solche Probleme nicht mehr gehabt und auch keine Meldung dieser Art mehr gesehen: [DCC Fehler] Project1.dpr(5): F2051 Unit IrgendEinName wurde mit einer unterschiedlichen Version von IrgendEinAndererName compiliert

Klar: Wenn man bei der Entwicklung (warum auch immer) unterschiedliche Versionen von Programmteilen ... vorhalten muss, ist das keine so besonders sinnvolle Vorgehensweise,
aber für die Hobbyprogrammierung reicht das aus ;-)

Amateurprofi 26. Sep 2016 23:59

AW: Zugriff auf andere Konstante als im Source Code angegeben
 
Vielen Dank für Eure Antworten.

@Bjoerk:
Das hatte ich gemacht.
"PianoKeyName" kam als Deklaration im gesamten Projekt nur 1 mal vor.
Alle anderen Fundstellen waren Zugriffe auf diese Konstante.

@hoika:
Auch dass hatte ich versucht; ohne Erfolg.

@mm1256:
"irgend ein Cache-Gedöns der IDE" war auch eine meiner Vermutung.
Wie in #1 erwähnt, hatte ich die Konstante auch in die Unit verschoben, in der ich darauf zugreifen wollte, was mit einer Exception endete.
Das sah für mich so aus als wäre beim Kompilieren die ursprüngliche Position der Konstanten verarbeitet worden, und zur Laufzeit krachte es dann.
Aber auch nach zwischenzeitlichem Arbeiten mit anderen Projekten und selbst nach runterfahren des Rechners blieb das Problem.

@nahpets:
Es gibt/gab genau 3 der Base.dcu.
Eine in …/win32/Debug im aktuellen Projekt.
Zwei in einem anderen Verzeichnis, in …/win32/Debug und …/win64/Debug.
Dieses andere Verzeichnis ist nicht im Suchpfad und zudem war die Konstante in diesen beiden noch nicht vorhanden.
Hintergrund ist, dass ich, wenn ich größere Änderungen vorhabe, vorher eine Kopie des Projektverzeichnis anlege, damit ich im Zweifelsfall bequem wieder zum alten Stand der Dinge zurückkommen kann.

Mir scheint, dass die Art, wie ich Teile der Deklaration entfernt hatte (Spaltenweises Löschen) die DIE durcheinander brachte.

jaenicke 27. Sep 2016 06:59

AW: Zugriff auf andere Konstante als im Source Code angegeben
 
Zitat:

Zitat von Amateurprofi (Beitrag 1348884)
Hintergrund ist, dass ich, wenn ich größere Änderungen vorhabe, vorher eine Kopie des Projektverzeichnis anlege, damit ich im Zweifelsfall bequem wieder zum alten Stand der Dinge zurückkommen kann.

Du beschreibst gerade genau die Funktionsweise einer Versionsverwaltung wie Git, SVN usw. ;-)
Da kannst du dir den ganzen Aufwand sparen und hast noch dazu deine Änderungen hinterher sauber geloggt um später noch nachvollziehen zu können was du warum geändert hast.

Zitat:

Zitat von nahpets (Beitrag 1348872)
Alle DCUs aller Projekte werden an einer Stelle abgelegt. Es gibt nur einen Ausgabepfad für Units.

Das Gegenteil wäre in der Regel sinnvoller. Ein DCU Verzeichnis pro Projekt, Konfiguration und Plattform (mit Platzhaltern im Pfad), damit IFDEFs funktionieren. Denn wenn sich nur eine Compilerdirektive ändert, die Unit aber nicht, wird diese nicht neu erzeugt. Das gibt dann auf den ersten Blick echt seltsame Fehler.

himitsu 27. Sep 2016 08:59

AW: Zugriff auf andere Konstante als im Source Code angegeben
 
Zitat:

Zitat von jaenicke (Beitrag 1348888)
Denn wenn sich nur eine Compilerdirektive ändert, die Unit aber nicht, wird diese nicht neu erzeugt.

Wenn man "Erzeugen" (Build) sagt, dann wird immer alles "neu erzeugt" aber beim "Kompilieren" (Cimpile) werden Units, die ale "unverändert" erkannt wurden und wozu eine DCU existiert, nicht neu "erzeugt" :stupid:

mm1256 27. Sep 2016 09:02

AW: Zugriff auf andere Konstante als im Source Code angegeben
 
Zitat:

Zitat von jaenicke (Beitrag 1348888)
....Denn wenn sich nur eine Compilerdirektive ändert, die Unit aber nicht, wird diese nicht neu erzeugt. Das gibt dann auf den ersten Blick echt seltsame Fehler.

Dieses Problem umgehe ich, indem ich für jedes größere Projekt eine .INC mit den entsprechenden Compilerdirektiven erzeuge, und die .INC dann in jede Unit einfüge. Das macht neben der Lösung dieses Problems ganz besonders viel Sinn, wenn man eindeutig zwischen DEBUG und RELEASE unterscheiden möchte/muss.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:28 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz