Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Hat Delphi Probleme mit static Variablen? (https://www.delphipraxis.net/11009-hat-delphi-probleme-mit-static-variablen.html)

frankg 29. Okt 2003 14:02


Hat Delphi Probleme mit static Variablen?
 
Hallo all!

Ich programmiere momentan mal wieder etwas durch die Gegend, und dabei ist mir folgendes aufgefallen: Kann es sein, dass Delphi Probleme damit hat, static Variablen auseinanderzuhalten? Zuerst mal worum geht es? Sprachen wie C++ unterstützen sogenannte static Variablen, das sind Variablen, die ihren Wert auch dann nicht verlieren, wenn die Funktion verlassen wird. Delphi bietet diese Variablen nicht direkt an, man kann aber ein ähnliches Verhalten erzeugen, indem man zuweisbare typisierte Konstanten verwendet (muss man für den Compiler explizit einschalten). Ich habe draufhin mal folgendes programmiert:

Delphi-Quellcode:
procedure Test1;
const
  TestStat : Boolean = TRUE;
begin
  if Bedingung1 then
    TestStat := TRUE
  else
    TestStat := FALSE;
end;

procedure Test2;
const
  TestStat : Boolean = TRUE;
begin
  if Bedingung2 then
    TestStat := TRUE
  else
    TestStat := FALSE;
end;
Die Idee hinter dieser Programmierung war, so etwas wie ein Statusflag für die Prozedur zu erzeugen. Der obige Versuch scheitert. TestStat, obwohl in beiden Prozeduren lokal definiert wird offensichtlich wie eine globale Variable verwendet. Ändert sich der Wert von TestStat in Test1, ändert sich der Wert von TestStat in Test2 auch und umgekehrt. Ich habe das auf den gleichen Namen zurückgeführt und daraufhin folgendes programmiert:

Delphi-Quellcode:
procedure Test1;
const
  TestStat1 : Boolean = TRUE;
begin
  if Bedingung1 then
    TestStat1 := TRUE
  else
    TestStat1 := FALSE;
end;

procedure Test2;
const
  TestStat2 : Boolean = TRUE;
begin
  if Bedingung2 then
    TestStat2 := TRUE
  else
    TestStat2 := FALSE;
end;
Das kuriose ist jetzt aber, dass trotz der unterschiedlichen Namen TestStat1 und TestStat2 gleich behandelt werden, d.h. ändert sich TestStat1, ändert sich TestStat2 auch automatisch. Hat von Euch schon jemand mal versucht so etwas zu programmieren? Ich weiss jetzt auch nicht, ob der Fehler bei mir oder bei Delphi liegt. Schon mal vielen Dank für (zahlreiche) Antworten.

Viele Grüsse

Frank :coder:

eXOs 29. Okt 2003 14:27

Re: Hat Delphi Probleme mit static Variablen?
 
es kann sein das ich dich nicht verstehe, aber was macht es einen sinn einen Schalter als Konstante zu vereinbaren?

frankg 29. Okt 2003 14:46

Re: Hat Delphi Probleme mit static Variablen?
 
Zitat:

Zitat von eXOs
es kann sein das ich dich nicht verstehe, aber was macht es einen sinn einen Schalter als Konstante zu vereinbaren?

Hi eXOs!

Also der Sinn, den ich hier verfolge ist es, eine Art "globale" Variable auf Prozedurebene zu haben, d.h. eine Variable, die ihren Wert nicht verliert, wenn man die Prozedur verlässt aber ausserhalb der Prozedur nicht sichtbar ist. Natürlich kann man dazu eine komplett globale Variable deklarieren (was unschön ist). Meine "globale" Variable soll nur im Scope der Prozedur sichtbar sein, in der sie definiert ist (sowas wie ein Merker, der an der Prozedur hängt). Wie ich in meinem Eingangs-Posting geschrieben habe unterstützen andere Sprachen wie C++ solche Konstrukte als statische Variable. Delphi selbst unterstützt keine statischen Variablen, man kann aber typisierte, zuweisbare Konstanten erzeugen, die sich ähnlich verhalten (siehe Code). Damit der Code läuft muss man in den Compiler-Eigenschaften noch einstellen, dass zuweisbare typisierte Konstanten verwendet werden sollen (unter Projekt->Optionen->Compiler). Ansonsten meckert Delphi (zu Recht) die Zuweisungsoperationen für die Konstante an.

Viele Grüsse

Frank

franz77 29. Okt 2003 15:09

Re: Hat Delphi Probleme mit static Variablen?
 
Hallo frankg!

Ich kenne static variablen aus C++ mit folgenden Bedeutungen. Zum einen kann eine static Variable die Gültigkeit innerhalb einer Quelltextdatei anzeigen, oder auf ein Attribut einer Klasse angewendet die Variable als Klassenvariable definieren, heißt die Varaible gehört dann nicht zur Instanz der Klasse, sondern zur Klasse selbst.
Bei Objekt Pascal kommt es meines Wissens nach darauf an, ob Du eine Variable im interface oder im implementation Teil definierst. Im interface Teil hat die Variable global Gültigkeit, im implementation Teil ist die Variable nur innerhalb der unit gültig.

Allerdings gibt es in Object Pascal die Möglichkeit Klassenfunktioninen zu definieren, das ist dann ganz ähnlich wie in c++ o. java.

Aber nochmal in Kürze, wenn Du die Deklaration deiner Boolean Variable in den implementationsteil deiner unit packst, dann ist das so wie eine statis variable in c++.

Gruss, Franz.

eXOs 29. Okt 2003 15:16

Re: Hat Delphi Probleme mit static Variablen?
 
Hi,

:oops: ok, glaube ich habs jetzt verstanden.Glaube aber mich daran errinnern zu können, das man keine Variablen die in einer Prozedur vereinbart worden sind, global zu verwenden, kann mich aber auch täuschen.

:( Ich bin dir nicht grad ne große Hilfe, oder? wenn ich hier nur Vermutungen anstelle.

franz77 29. Okt 2003 15:32

Re: Hat Delphi Probleme mit static Variablen?
 
Hallo nochmal Zusammen!

Langsam kapier ich es nicht mehr. Also zusammengefasst meinte ich folgendes:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TForm1 = class(TForm)
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1; // ist nach aussen sichtbar

implementation
var
  Form1NurFuerUnit: TForm1; // ist nur innerhalb des implementationsteils
                            // der unit sichtbar
{$R *.DFM}

end.
Hier wäre die Variable Form1 für eine andere unit sichtbar, die Variable Form1NurFuerUnit aber nicht. Wenn ich eine nichtglobale Variable haben wollte, die nur für die Funktionen der einen unit sichtbar sein soll würde ich sie in den Implementationsteil stecken.

Gruss, Franz.

woki 29. Okt 2003 15:35

Re: Hat Delphi Probleme mit static Variablen?
 
Zitat:

Zuweisbare typisierte Konstanten Diese Option dient der Abwärtskompatibilität zu Delphi 1.0 unter Windows. Wenn sie aktiviert ist, unterstützt der Compiler Zuweisungen an typisierte Konstanten. Sie entspricht dem Schalter {$J}.
Ich nehme an, Du hättest gerne eine Variable, deren Lebensdauer die Lebensdauer des Programmes ist, deren Sichtbarkeit aber auf eine Funktion beschränkt ist. Diese zuweisbaren typisierten Konstanten sind da so eine Notlösung, aber bei Dingen, die nur wegen der Abwärtskompatibilität vorhanden sind, wäre ich grundsätzlich vorsichtig bei der Verwendung. Nur innerhalb der Unit sichtbare Variablen, wie oben beschrieben, sind dann da bei Delphi vielleicht doch der Weg der Wahl.

Grüsse
Woki

Niko 29. Okt 2003 16:02

Re: Hat Delphi Probleme mit static Variablen?
 
Zitat:

Zitat von woki
Zitat:

Zuweisbare typisierte Konstanten Diese Option dient der Abwärtskompatibilität zu Delphi 1.0 unter Windows. Wenn sie aktiviert ist, unterstützt der Compiler Zuweisungen an typisierte Konstanten. Sie entspricht dem Schalter {$J}.
[...]
bei Dingen, die nur wegen der Abwärtskompatibilität vorhanden sind

Ich denke diese Option dient eher andersherum der Abwärtskompatibilität, denn unter Delphi Version >= 2 sind zuweisbare typisierte Konstanten (also $J+) der Standard.

Was das Phänomen mit den lokalen Konstanten anbelangt: Könnte es sein, dass diese Konstanten bei jedem Aufruf der Prozedur erneut initialisiert werden und deshalb als static-Ersatz ungeeignet sind?

woki 29. Okt 2003 16:32

Re: Hat Delphi Probleme mit static Variablen?
 
Zitat:

Zitat von Niko
Zitat:

Zitat von woki
Zitat:

Zuweisbare typisierte Konstanten Diese Option dient der Abwärtskompatibilität zu Delphi 1.0 unter Windows. Wenn sie aktiviert ist, unterstützt der Compiler Zuweisungen an typisierte Konstanten. Sie entspricht dem Schalter {$J}.
[...]
bei Dingen, die nur wegen der Abwärtskompatibilität vorhanden sind

Ich denke diese Option dient eher andersherum der Abwärtskompatibilität, denn unter Delphi Version >= 2 sind zuweisbare typisierte Konstanten (also $J+) der Standard.

Wird bestritten...
Als Hinweise:
- Das Zitat stammt direkt aus der Delphidokumentation
- Ich hab das nochmal schnell in einer recht frischen Delphiinstallation nachgeschaut, Default ist off.



Zitat:

Was das Phänomen mit den lokalen Konstanten anbelangt: Könnte es sein, dass diese Konstanten bei jedem Aufruf der Prozedur erneut initialisiert werden und deshalb als static-Ersatz ungeeignet sind?
Ne, in diesem Punkt verhalten sie sich schon wie gewünscht, ihre Lebensdauer ist die Lebensdauer des Programms, hab ich grad nochmal getestet.

Grüsse
Woki

SirThornberry 29. Okt 2003 16:40

Re: Hat Delphi Probleme mit static Variablen?
 
seit wann nimmt man überhaupt "const" bei variablen?? "const" ist Konstant und "var" ist variabel. Da geht es doch schon theoretich nicht das man etwas constantes ändert...

Niko 29. Okt 2003 16:41

Re: Hat Delphi Probleme mit static Variablen?
 
Zitat:

Zitat von woki
Wird bestritten...

Dein Zitat hab ich auch gefunden. Aber unter Typisierte Konstanten steht bei mir
Zitat:

Zitat von Delphi-Hilfe
Im Standardstatus des Compilers ({$J+}) können typisierten Konstanten neue Werte zugewiesen werden. Sie entsprechen damit initialisierten Variablen.

Aber vielleicht hat sich das seit Delphi 4 ja schon wieder geändert :? .

Daniel B 29. Okt 2003 17:47

Re: Hat Delphi Probleme mit static Variablen?
 
Hi,
Zitat:

Zitat von franz77
Delphi-Quellcode:
var
  Form1: TForm1; // ist nach aussen sichtbar

implementation
var
  Form1NurFuerUnit: TForm1; // ist nur innerhalb des implementationsteils
                            // der unit sichtbar
{$R *.DFM}

end.

Die Variable Form1NurFürunit ist natürlich nur noch nach unten bekannt.

Das ist da gleiche als wenn Du es gleich zwischen Prozeduren und Funktionen schreiben würdest:
Delphi-Quellcode:
procedure Blupp1;
begin
//
end;

var
  sMyVar: String;

procedure Blupp2;
begin
//
end;
Die Variable sMyVar ist nur noch da verfügbar, was danach kommt, also z.B. in der Prozedur Blupp2, aber nicht in Blupp1.

woki 29. Okt 2003 18:40

Re: Hat Delphi Probleme mit static Variablen?
 
Zitat:

Zitat von SirThornberry
seit wann nimmt man überhaupt "const" bei variablen?? "const" ist Konstant und "var" ist variabel. Da geht es doch schon theoretich nicht das man etwas constantes ändert...

Na ja, sollte man glauben, aber bei Delphi unterscheidet man tatsächlich zwischen echten und typisierten Konstanten :x

Zitat:

Aber vielleicht hat sich das seit Delphi 4 ja schon wieder geändert
So wird es dann wohl sein, denn bei Delphi 7

Zitat:

Typ Schalter
Syntax {$J+} oder {$J-}
{$WRITEABLECONST ON} oder {$WRITEABLECONST OFF}
Vorgabe (Kontrollfeld) {$J-}
{$WRITEABLECONST OFF}
Grüsse
Woki

SirThornberry 29. Okt 2003 19:35

Re: Hat Delphi Probleme mit static Variablen?
 
wie jetzt, soll das heißen das man auch variablen die hinter "const" definiert wurden ändern kann??? hab das no gar ni probiert da ich das von C++ her nur so kenne das es nicht änderbar ist

woki 29. Okt 2003 22:19

Re: Hat Delphi Probleme mit static Variablen?
 
Zitat:

Zitat von SirThornberry
wie jetzt, soll das heißen das man auch variablen die hinter "const" definiert wurden ändern kann???

Auch wenn das ein sehr unglückliches Konsrukt ist, ja das geht, also

Dinge der Art

const Bezeichner = Wert sind echte Konstanten und nicht veränderbar.

Aber

const Bezeichner :Typ = Wert und unter Projekt|Optionen|Compiler sind zuweisbare typisierte Konstanten aktiviert, dann gehts, um Überraschungen zu vermeiden, sollte man hier aber genau wissen was man tut, und sicher sein, das man das wirklich braucht.

Grüsse
Woki

frankg 30. Okt 2003 08:31

Re: Hat Delphi Probleme mit static Variablen?
 
Zitat:

Zitat von woki
Zitat:

Zuweisbare typisierte Konstanten Diese Option dient der Abwärtskompatibilität zu Delphi 1.0 unter Windows. Wenn sie aktiviert ist, unterstützt der Compiler Zuweisungen an typisierte Konstanten. Sie entspricht dem Schalter {$J}.
Ich nehme an, Du hättest gerne eine Variable, deren Lebensdauer die Lebensdauer des Programmes ist, deren Sichtbarkeit aber auf eine Funktion beschränkt ist. Diese zuweisbaren typisierten Konstanten sind da so eine Notlösung, aber bei Dingen, die nur wegen der Abwärtskompatibilität vorhanden sind, wäre ich grundsätzlich vorsichtig bei der Verwendung. Nur innerhalb der Unit sichtbare Variablen, wie oben beschrieben, sind dann da bei Delphi vielleicht doch der Weg der Wahl.

Grüsse
Woki

Hi Woki!

Ganz genau. Ich will eine gobale Variable mit Sichtbarkeit die auf eine Funktion beschränkt ist. Die soll im Prinzip den Status der Funktion wiederspiegeln. Aus Gründen des "least privilege" soll die Variable halt nur in der Funktion bekannt sein. Sicherlich könnte ich (als Notlösung) auch eine unit-globale Variable verwenden, mich wundert es aber trotztdem, dass das mit den typisierten Konstanten nicht so funktioniert, wie ich es programmiert habe.

Viele Grüsse

Frank

woki 30. Okt 2003 09:21

Re: Hat Delphi Probleme mit static Variablen?
 
Hi Frank,

ich kann allerdings Dein Problem nicht reproduzieren, hab das mal mit Booleans und mit Integern probiert, und bei mir gibt es keine Prozedurübergreifende Beeinflussung.

Delphi-Quellcode:
procedure TForm1.Button4Click(Sender: TObject);
const hallo : integer =2;
      testbool :Boolean=true;
begin
  hallo := hallo+1;
  ShowMessage(inttostr(hallo));
  testbool := NOT testbool;
  showmessage(BoolToStr(testbool,true));
end;

procedure TForm1.Button6Click(Sender: TObject);
const hallo : integer =2;
      testbool :Boolean=true;
begin
  hallo := hallo+1;
  ShowMessage(inttostr(hallo));
  showmessage(BoolToStr(testbool,true));
end;
[edit=Daniel B]Delphi-Tags korrigiert. Mfg, Daniel B[/edit]

choose 2. Nov 2003 18:48

Re: Hat Delphi Probleme mit static Variablen?
 
Hey Frank,

Delphi hat keine Probleme bei Namensgleichheit von Identifiern. Es gilt lediglich den Scope und Namespace (ab D7) korrekt zu verwenden. Du kannst mithilfe des Debuggers der Delphi-IDE leicht überprüfen, ob zwei (einfache) Variablen identisch sind, also den selben Speicherplatz einnehmen, indem Du ihre Adressen auf Gleichheit überprüfst. Der integrierte Debugger und die Watch List (Strg+Alt+W) eignen sich zur Laufzeit prima, wenn Du Ausdrücke der Art @myVar auswerten lässt (in der IDE Strg+F5).

In diesem Beispiel:
Delphi-Quellcode:
{$J+}
procedure StaticVar42;
const
  myVar : Integer = 42;
begin
  Inc(myVar);
end;

procedure StaticVar137;
const
  myVar : Integer = 137;
begin
  Inc(myVar);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Test42;
  Test137;
end;
ergibt der Ausdruck @myVar innerhalb von StaticVar42 zB den Wert @myVar:$44EBC0 und innerhalb von StaticVar127 den Wert @myVar:$44EBC4. Die beiden zuweisbaren Konstanten (assignable typed constants) nehmen also nicht den selben Speicherplaz ein und sind folglich nicht identisch.

Du kannst den integrierten Debugger nun mithilfe der ermittelten Adresse verwenden, um den Inhalt der beiden Variablen auch "von außerhalb" abzufragen, indem Du die Ausdrücke PInteger($44EBC0)^ bzw. PInteger($44EBC0)^ abfragst.

Tatsächlich handelt es sich bei zuweisbaren Konstanten immer (egal ob Methode, lokale Prozedur oder global) um Variablen im Datensegment, sie sind daher auch außerhalb der Prozedur/Methode gültig (Rückgabe von Pointern auf dieser Konstanten sind zulässig) und werden von allen Threads gemeinsam verwendet. Ein
Delphi-Quellcode:
static threadvar myVar = 123;
oder
Delphi-Quellcode:
threadconst myVar = 123;
gibt es leider nicht ;(

HTH


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