Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi komisches Verhalten mit OleVariant (https://www.delphipraxis.net/211063-komisches-verhalten-mit-olevariant.html)

fisipjm 22. Jul 2022 16:24

komisches Verhalten mit OleVariant
 
Hi,

kann mir jemand dieses komische Verhalten erklären welches ich mit einem kleinen Beispielcode nachgestellt habe.
Ich habe die Funktion auf eine VCL Form mit Button und Edit gelegt und lass mir nach Klick auf den Button das Result ins Edit schreiben.

Delphi-Quellcode:
function TForm1.GetInitIntegerOleVariant: String;
var
  I : Integer;
  Iole : Olevariant;
begin
  varclear(Iole);
  Iole := I;
  Result := iOle;
end;
Ich bin darauf gestoßen, weil mir das Verhalten nämlich in einem Projekt um die Ohren geknallt ist. Laut Definition ist jede Integer Variable nach ihrer Initialisierung 0. Wenn ich sie aber in ein Olevariant werfe und nich über vartostr gehe, sondern direkt in einen String caste, dann kommt beim ersten Aufruf irgendwas wildes raus. Beim 2. Aufruf kommt immer die 0.

Gruß
PJM

Papaschlumpf73 22. Jul 2022 16:29

AW: komisches Verhalten mit OleVariant
 
So etwas hatte ich auch schon mal. Bin mir aber nicht mehr sicher, ob das mit OLEVariant zu tun hatte. Die Integer waren aber auch nicht immer 0. Damals hatte ich mir angewöhnt, alle Integer:=0 zu setzen, wenn diese nicht direkt einen festen anderen Wert bekommen.

Der schöne Günther 22. Jul 2022 16:31

AW: komisches Verhalten mit OleVariant
 
Zitat:

Zitat von fisipjm (Beitrag 1509077)
Laut Definition ist jede Integer Variable nach ihrer Initialisierung 0

Und wo wird
Delphi-Quellcode:
I
initialisiert? Du hast sie deklariert, aber nirgends initialisiert.
Es steht also erst einmal irgend etwas drin. Wenn du möchtest dass eine Null drinsteht kannst du sagen
Delphi-Quellcode:
i := 0
oder
Delphi-Quellcode:
i := Default(Integer)
.

fisipjm 22. Jul 2022 16:38

AW: komisches Verhalten mit OleVariant
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1509079)
Zitat:

Zitat von fisipjm (Beitrag 1509077)
Laut Definition ist jede Integer Variable nach ihrer Initialisierung 0

Und wo wird
Delphi-Quellcode:
I
initialisiert? Du hast sie deklariert, aber nirgends initialisiert.
Es steht also erst einmal irgend etwas drin. Wenn du möchtest dass eine Null drinsteht kannst du sagen
Delphi-Quellcode:
i := 0
oder
Delphi-Quellcode:
i := Default(Integer)
.

Das stimmt nicht. Bei anderen Programmiersprachen mag das stimmen. Bei Delphi sind Integer und Bool aber per default nach ihrer deklaration immer 0 bzw false. Ich finde gerade leider die Source dazu nicht mehr...
Wenn du eine Funktion schreibst in der du einfach nur I.tostr machst, wird immer 0 dabei heraus kommen.

edit: Hab grad gesehen das der Compiler mir die Info schmeist:
[dcc32 Warnung] Unit1.pas(47): W1036 Variable 'I' ist möglicherweise nicht initialisiert worden

Das macht er bei i.tostring nicht. Wieso?

fisipjm 22. Jul 2022 16:43

AW: komisches Verhalten mit OleVariant
 
Zitat:

Zitat von Papaschlumpf73 (Beitrag 1509078)
So etwas hatte ich auch schon mal. Bin mir aber nicht mehr sicher, ob das mit OLEVariant zu tun hatte. Die Integer waren aber auch nicht immer 0. Damals hatte ich mir angewöhnt, alle Integer:=0 zu setzen, wenn diese nicht direkt einen festen anderen Wert bekommen.

Führt aber häufog dazu, dass der Compiler meckert und sagt, dass der Wert welcher zugewiesen wurde niemals verwendet wird. Denn in den seltensten Fällen beleibt der Wert unberührt.

Uwe Raabe 22. Jul 2022 16:46

AW: komisches Verhalten mit OleVariant
 
Zitat:

Zitat von fisipjm (Beitrag 1509080)
Bei Delphi sind Integer und Bool aber per default nach ihrer deklaration immer 0 bzw false.

Das gilt nur für globale Variablen und Felder einer Klasse. Einfache lokale Variablen (also keine string, interface oder so) werden nicht initialisiert.

Variables (Delphi)

Zitat:

If you do not explicitly initialize a global variable, the compiler initializes it to 0. Object instance data (fields) are also initialized to 0. The contents of a local variable are undefined until a value is assigned to them.

fisipjm 22. Jul 2022 16:50

AW: komisches Verhalten mit OleVariant
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1509083)
Zitat:

Zitat von fisipjm (Beitrag 1509080)
Bei Delphi sind Integer und Bool aber per default nach ihrer deklaration immer 0 bzw false.

Das gilt nur für globale Variablen und Felder einer Klasse. Einfache lokale Variablen (also keine string, interface oder so) werden nicht initialisiert.

Variables (Delphi)

Zitat:

If you do not explicitly initialize a global variable, the compiler initializes it to 0. Object instance data (fields) are also initialized to 0. The contents of a local variable are undefined until a value is assigned to them.

Aha, das war das Problem. Danke. Seltsam das da ein Unterschied zwischen global und local gemacht wird....

himitsu 22. Jul 2022 23:03

AW: komisches Verhalten mit OleVariant
 
Das ist/war eine Optimierung. gesparte Zeit, wenn nicht ständig im Speicher rumgeschrieben wird (Initialisierung bei Funktionsstart).

Aber mal ganz im Ernst, warum hörst du nicht auf deinen Compiler, welcher dir gesagt haben sollte, dass diese Variable nicht initialisiert ist?



PS: Result wird auch nicht initialisiert.
Hier hast du sogar einen bösen sonderfall, weil es ein String (gemangter Typ) ist.
Nur mit dem Problem, dass das Result (dieser String) nicht dort initialisiert wird, wo du vielleicht denkst.
Hier nicht beim Aufruf der Funktion, sondern beim Aufrufer der Funktion, wo der Speicher für "dieses" Result her kommt. (bei gemagten Typen)



Globale Variablen liegen auf dem Heap, in einem Speicherbereich, welche von Windows bereitgestellt wird, wenn das Modul (EXE oder DLL) geladen wird.
Ebenso sieht es mit Thread-Variablen aus, wo der Speicherbereich beim erstellen des Threads bereitgestellt wird.

Speicher von Windows, ebenso wie aus VirtualAlloc, wird immer mit 0 initalisiert.



Lokale Variablen liegen aber auf dem Stack, welcher zwar zu Beginn (Program/Thread) zwar auch 0 ist, aber dort wird nie gelöscht
und bei Funktionseintritt auch nicht von Delphi neu geleert.
Außnahme sind gemanagte Typen, wie Variant, Interface, String, dynamische Arrays und neuerdings (bedingt) auch Managed Custom Records.
Grund ist die automatische Speicherverwaltung, welche nur funktionieren kann, wenn es einen definierten Zustand gibt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:46 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