Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Zuweisung an prozedularer Variable prüfen


Daniel L. - Di 01.02.11 23:34
Titel: Zuweisung an prozedularer Variable prüfen
Hi,

ich hab eine prozedulare Variable einer regulären Prozedur (also keiner Methode)
Wie kann man prüfen, ob dieser Variablen ein Wert zugewiesen wurde?
Assigned (RegulaerProcVar) ist immer true, nützt also nichts.

Gruss: Daniel


bummi - Di 01.02.11 23:48

Würde ich Aufgaben des Aufrufers sehen, meinst Du sowas?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
unit Unit1;

interface

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

type
  TP=Procedure (i:Integer);
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

Procedure Test(PP:TP);
begin
  if Assigned(pp) then PP(12);

end;

Procedure P(i:Integer);
begin
  Showmessage(IntToStr(i))
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   Test(nil);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
   Test(p);

end;

end.


Daniel L. - Mi 02.02.11 00:06

nicht als Parameter, sondern so:



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
unit Unit2;

interface

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

type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

  procedure aktion;
  procedure test;



var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure aktion;
begin
  showmessage ('tralala');
end;

procedure test;
var p : procedure;
begin
  p := aktion;
  if assigned (p)  then p;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
  test;
end;

end.


lasse ich die Zuweisung an p weg, wird trotzdem versucht p auszuführen, es kommt dann die Fehlermeldung "priviligerte Anweisung"


bummi - Mi 02.02.11 00:28

klar p ist in diesem Fall eine nicht initialisierte Stackvariable, da steht sonst was drin....


Daniel L. - Mi 02.02.11 00:42

und wie kann auf Initialisierung prüfen?


bummi - Mi 02.02.11 00:59

was genau hast Du vor? Dein Beispiel...

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure test;
var p : procedure;
begin
  p := aktion;
  if assigned (p)  then p;
end;


wenn Du p := aktion; weg lässt steht in p das drin was halt gerade auf dem Stack liegt....
In meinem Beispiel wird es übergeben oder nicht (nil)
Wenn Du eine Klassen oder globale Variable verwendest ist es bei der Klassenvariable mit nil initalisiert, bei einer globalen Variablen muß Du es selbst mit nil initialisieren und wenn gewünscht die Prozedur zuweisen.
Das Testbeispiel verrät mit nichts über Deine Absichten da es per se sinnlos ist ;-)


Daniel L. - Mi 02.02.11 01:23

Ich hab nichts konkretes vor, sondern spiele nur ein bisschen rum :wink:

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:

Wenn Du eine Klassen oder globale Variable verwendest...


meintest du vielleicht "...oder lokale Variable verwendest..."

Ich hab p mal global definiert, jetzt wird mit nil vorinitialisiert, also so, wie ich es eigentlich erwartet hatte.


bummi - Mi 02.02.11 01:32

Du kannst Dich nur bei Klassenvariablen darauf verlassen, Stackvariablen sind nie initialisiert (Ausnahme Strings), globale Variablen müssen ebenfalls initalisiert werden.


jaenicke - Mi 02.02.11 05:15

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
globale Variablen müssen ebenfalls initalisiert werden.
Müssen nicht, nein, denn es ist dokumentiertes Verhalten, dass das automatisch passiert.
Delphi Hilfe [http://docwiki.embarcadero.com/RADStudio/de/Variablen] hat folgendes geschrieben:
Wenn Sie eine globale Variable nicht explizit initialisieren, wird sie vom Compiler mit 0 initialisiert. Objektinstanzdaten (Felder) werden auch mit 0 initialisiert. Auf der Wiin32-Plattform ist der Inhalt von lokalen Variablen so lange undefiniert, bis ein Wert zugewiesen wird.
Bei einer lokalen Variable wäre es aber auch Blödsinn diese vom Compiler immer vorzubelegen. Das würde nur unnötig Rechenzeit kosten. Normalerweise ist der Bereich einer lokalen Variablen so klein, dass es sich relativ leicht überblicken lässt, was mit der Variablen passiert.
Wenn man dann nicht immer etwas zuweist, kommt ja auch eine Compilerwarnung. Dann kann man im anderen Fall einfach z.B. nil selbst zuweisen.

Daraus dann ohne die Notwendigkeit eine globale Variable zu machen, nur weil man zu faul ist, die Variable in den Fällen zu initialisieren, in denen das nicht ohnehin schon passiert, ist kein guter Programmierstil... :roll:


bummi - Mi 02.02.11 08:52

Danke für die Klarstellung....