AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Die Delphi-IDE IDE: Compiler Einstellung für nicht initialisierte Variablen

IDE: Compiler Einstellung für nicht initialisierte Variablen

Ein Thema von Athris · begonnen am 10. Sep 2021 · letzter Beitrag vom 10. Sep 2021
Antwort Antwort
Seite 1 von 2  1 2   
Athris

Registriert seit: 18. Nov 2014
28 Beiträge
 
Delphi XE2 Professional
 
#1

IDE: Compiler Einstellung für nicht initialisierte Variablen

  Alt 10. Sep 2021, 09:52
Guten Morgen zusammen,

wir haben lange Zeit Delphi XE2 für die Kompilierung von verschiedenen Projekten genutzt.
Vor Kurzem benutzen wir nun parallel Delphi 10.4 und migrieren Stück für Stück unsere Projekte auf die neue IDE und von 32bit auf 64bit.

Hierbei ist uns nun etwas seltsames aufgefallen. Zuerst einmal einen Auszug aus dem Quellcode:
Delphi-Quellcode:
procedure TfrmMain.OnExitEdit;
var
  txtOrt, txtPLZ, txtLand, txtStrasse, txtBundesland: TEdit;
  strCheck: String;
begin
  if (Sender=nil) or (not (Sender is TEdit)) then exit;
  txtStrasse := nil;
  txtBundesland := nil;
  try
    //...
    //Nicht relevanter Quellcode entfernt
    //...
    else if pos( 'LAND', TEdit(Sender).Name)>0 then begin
      txtLAND := TEdit( Sender);
      txtLand.Text := CheckLandIso3( Databasename, txtLand.Text);
    end
    else begin
      exit;
    end;
  except
    on E:Exception do begin
      ShowMessage( E.Message);
      exit;
    end;
  end;
  //Hier tritt die Zugriffsverletzung unter 10.4 auf, während diese bei Delphi XE2 keine Zugriffsverletzung auftritt
  strCheck := GetGeoCheckAdressString( txtLand.Text, txtPLZ.Text, txtOrt.Text, txtStrasse.Text);
Delphi-Quellcode:
function GetGeoCheckAdressString( const vstrLand, vstrPLZ, vstrOrt, vstrStrasse: String): String;
begin
  Result := strSimple( vstrLand+vstrPLZ+vstrOrt+vstrStrasse);
end;

Die Funktion liefert unter Delphi 10.4 eine Zugriffsverletzung (was in unseren Augen korrekt ist, da die Variable gar nicht initiiert ist).
Unter Delphi XE2 kommt es aber zu keiner Zugriffsverletzung.

Nun sind wir etwas ratlos warum dies so ist. Gibt es eventuell eine Compiler Einstellung die solch ein Verhalten steuert?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.014 Beiträge
 
Delphi 12 Athens
 
#2

AW: IDE: Compiler Einstellung für nicht initialisierte Variablen

  Alt 10. Sep 2021, 10:43
Erstmal sollte dir der Compiler schon länger eine Fehlermeldung geben, dass Variablen nicht initialisiert seien. (die zwei, welche vorher nicht auf NIL gesetzt wurden)
Somit ist ihr Wert per se zufällig, jenachdem was grade auf dem Stack vorher dort rumlag.

Aber auch NIL hilft nicht viel, da du ja auf Eigenschaften der Objekt-Instanz zugreifen willst.

Und dank dem EXIT können da unten somit alle Variablen sowohl einen Wert, NIL oder "sonstwas" drin haben. (man sieht nicht alles an Code, aber NIL ist vielleicht abgefangen, also somit eigentlich garnicht nötig)


Es ginge auch so:
Oben auf ALLES auf NIL setzen
und Unten darauf prüfen
Oder besser einfach direkt in der Funktion.
Und das Exit-gehopse auch weg.

Hier würde auch was angezeigt, wenn nur ein Edit nicht gefunden wurde.
Delphi-Quellcode:
strCheck := GetGeoCheckAdressString(txtLand, txtPLZ, txtOrt, txtStrasse);

...

function GetGeoCheckAdressString(vtxtLand, vtxtPLZ, vtxtOrt, vtxtStrasse: TEdit): String;
begin
  Result := '';
  if Assigned(vtxtLand) then Result := Result + vtxtLand.Text; // wirklich ohne sowas wie z.B. ein ' ' dazwischen?
  if Assigned(vtxtPLZ) then Result := Result + vtxtPLZ.Text;
  if Assigned(vtxtOrt) then Result := Result + vtxtOrt.Text;
  if Assigned(vtxtStrasse) then Result := Result + vtxtStrasse.Text;
  Result := strSimple(Result);
end;
Nja, ohne das sinnlose Try-Except wird die Behandlung auch gleich viel Einfacher.
* entweder oben :=nil oder unten mit Exit raus -> Beides ist eigentlich nicht nötig, da entweder zugewiesen oder raus



PS:

Statt Pos<>0 ist Delphi-Referenz durchsuchenContainsStr (Delphi-Referenz durchsuchenContainsText) besser lesbar/verstehbar.
Steht "LAND" wirdklich irgendwo im String, oder meinst nicht eher sowas wie Delphi-Referenz durchsuchenStartsStr oder EndsStr? (bzw. StartsText oder EndsText)

Außerdem ist ShowMessage als "Fehlermeldung" nicht nur grauenhaft anzusehn,
sondern auch später extrem unproduktiv, wenn man mal ein richtiges Error-Management nuzten wöllte.
> Hier am Einfachsten diesen Try-Except-"Mist" weglassen.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (10. Sep 2021 um 10:56 Uhr)
  Mit Zitat antworten Zitat
Athris

Registriert seit: 18. Nov 2014
28 Beiträge
 
Delphi XE2 Professional
 
#3

AW: IDE: Compiler Einstellung für nicht initialisierte Variablen

  Alt 10. Sep 2021, 11:04
Der Quellcode ist tatsächlich sehr alt (bestimmt über 15 Jahre). Das die Qualität des Codes eher mangelhaft ist, ist mir bewusst

Die Frage ist nur warum XE2 niemals eine Zugriffsverletzung anzeigt (ist halt nie aufgefallen) und Delphi 10.4 immer eine Zugriffsverletzung anzeigt.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.286 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: IDE: Compiler Einstellung für nicht initialisierte Variablen

  Alt 10. Sep 2021, 11:09
Die Frage ist nur warum XE2 niemals eine Zugriffsverletzung anzeigt (ist halt nie aufgefallen) und Delphi 10.4 immer eine Zugriffsverletzung anzeigt.
Das ist eben Zufall. Da steht nun zufällig etwas im Speicher, was beim Zugriff eine nicht zugreifbare Adresse ist. Du hattest vorher schlicht Glück, dass in der Variablen ein Wert stand, von dem aus eine Adresse berechnet werden konnte, an der ein Zugriff möglich war. Und dass an der Stelle dann etwas war, das man in dem String nicht sehen konnte / nicht bemerkt wurde.

Wichtig ist vor allem, dass du keine Compilermeldungen (Variable nicht initialisiert, ...) ignorierst, wenn du die Anwendung erzeugst. Damit hast du schon viele mögliche Fehlerquellen vermieden.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.014 Beiträge
 
Delphi 12 Athens
 
#5

AW: IDE: Compiler Einstellung für nicht initialisierte Variablen

  Alt 10. Sep 2021, 11:11
Es kommt drauf an, was da im Speicher/Stack steht.

Wenn da irgendwas stand, was als Pointer interpregiert und mit einem kleinen Offset versehen (zu FHandle) auf reservierten Speicher zeigt, dann kann das als HWND für WM_GETTEXT genommen werden.
Selbst wenn dieses "HWND" ungültig ist, würde es keinen Fehler geben, da Delphi davon das Result/GetLastError nicht auswertet und somit nur einen Leertext liefert.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Athris

Registriert seit: 18. Nov 2014
28 Beiträge
 
Delphi XE2 Professional
 
#6

AW: IDE: Compiler Einstellung für nicht initialisierte Variablen

  Alt 10. Sep 2021, 11:24
Danke für eure Antworten, doch bleibe ich etwas skeptisch bei der Antwort "Es ist zufall".

Das kann kein Zufall sein. Der Programmabschnitt ist jahrelang bei über 150 Kunden im Einsatz gewesen. Auch bei uns selbst wurde der Abschnitt diverse mal aufgerufen und es kam NIE zu einer Zugriffsverletzung.

Beim neuen Delphi 10.4 kommt die Zugriffsverletzung jedes mal. Immer. Das kann doch kein Zufall sein.

Oder hat es etwas damit zu tun das wir bei XE2 immer nur in 32 bit kompiliert haben und nun beim 10.4 in 64bit kompilieren?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.014 Beiträge
 
Delphi 12 Athens
 
#7

AW: IDE: Compiler Einstellung für nicht initialisierte Variablen

  Alt 10. Sep 2021, 11:29
Für lokale Variablen und Result wird Speicher nicht initialisiert. (Ausnahme sind gemanagte Typen wie String oder Interface, wo Delphi von sich aus das Speichermanagement sicherstellen muß)

Sie haben also den Wert, welcher ein vorhergehender Funktionsaufruf dort auf dem Stack hinterlassen hatte.


Es "kann" immer der selbe Wert sein, wenn die Aufrufe in gleicher Reihenfolge sind, aber es muß nicht und somit ist der Wert "unbestimmt", also zufällig.
Und wenn ein neuer Compiler anderen Code erzeugt oder Variablen anders im Speicher ablegt, dann ist es nunmal plötzlich anders.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (10. Sep 2021 um 11:36 Uhr)
  Mit Zitat antworten Zitat
Athris

Registriert seit: 18. Nov 2014
28 Beiträge
 
Delphi XE2 Professional
 
#8

AW: IDE: Compiler Einstellung für nicht initialisierte Variablen

  Alt 10. Sep 2021, 11:32
Mit der Antwort kann ich leben, vielen Dank!
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.286 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: IDE: Compiler Einstellung für nicht initialisierte Variablen

  Alt 10. Sep 2021, 11:46
Oder hat es etwas damit zu tun das wir bei XE2 immer nur in 32 bit kompiliert haben und nun beim 10.4 in 64bit kompilieren?
Da gibt es diverse Unterschiede. Einer davon, der für die Exceptionbehandlung wichtig ist:
Bei 32-Bit Programmen ist der Stackframe nicht fest. Deshalb ist es nicht so einfach möglich, nach einem Fehler einen sauberen Stacktrace aufzubauen.
Bei 64-Bit Programmen gibt es dafür eindeutige Vorgaben, so dass man in der Regel auch zuverlässige Stacktraces bekommt.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.091 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

AW: IDE: Compiler Einstellung für nicht initialisierte Variablen

  Alt 10. Sep 2021, 11:48
Ich kann nichts mehr hinzufügen, genauso wie erklärt ist es.

Ich kann nur aus eigener Erfahrung berichten dass wir exakt den Fall auch hatten- Eine alte, nicht mehr gewartete Delphi-DLL mit so vielen Warnmeldungen über nicht initialisierte Variablen dass da auch keiner mehr geschaut hat. Lief viele Jahre lang.

Als sie eines Tages durch einen neueren Delphi-Compiler gejagt wurde gingen vereinzelte Dinge nicht mehr, keiner wusste weshalb. Lösung war exakt das gleiche: Eine nicht initialisierte Variable führte zu einer Zugriffsverletzung, und früher hat es bei einem älteren Compiler grade so gepasst dass nichts in sich zusammenbrach...
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:19 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