Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Funktionen verschachteln?


Horschdware - Fr 26.03.04 00:07
Titel: Funktionen verschachteln?
High
mein Infolehrer hat heute nen Gag versucht indem er (sinngemäß) folgendes gezeigt hat:


Delphi-Quelltext
1:
2:
3:
4:
5:
function Blahana(param1, param2 : integer) : integer;
begin
  function Sonstwas(was, weiss, ich : string) : boolean;
  begin
....


Kurz: Eine Funktion innerhalb einer Funktion.
Das hat natürlich nicht funktioniert, allerdings stellt sich mir da die Frage: Wäre so etwas überhaupt möglich, wenn man es gescheit machen würde?
Kann man Funktionen derart verschachteln?
Was meint ihr dazu?


Raphael O. - Fr 26.03.04 00:11

das funktioniert, wenn man die innere funktion vor dem begin deklariert...
sie ist dann aber auch nur innerhalb der äußeren funktion verfügbar


Brueggendiek - Fr 26.03.04 00:15
Titel: Re: Funktionen verschachteln?
Hallo!

Natürlich geht das "Verschachteln" von Prozeduren und Funktionen - man muß es nur richtig schreiben. Überall dort, wo Deklarationen erlaubt sind, kann man auch Prozeduren/Funktionen deklarieren.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
function Blahana(param1, param2 : integer) : integer;
  function Sonstwas(was, weiss, ich : string) : boolean;
  begin
....
  end { function Sonstwas };

begin
....
end { function Blahana };


Die Funktion "Sonstwas" kann dann nur innerhalb von "Blanaha" aufgerufen werden. Sie kann allerdings auf alle Variablen (auch die Parameter) der umgebenden Funktion zugreifen.

Gruß

Dietmar Brüggendiek


MaxiTB - Fr 26.03.04 00:16

Jo - kann nur beipflichten - sowas gibts unter object pascal. Dafür gibts keine sub-Klassen oder Typen (die man sehr oft brauchen kann).

Najo - da hat wahrscheinlich eine Tipse die Begriffe Methode/Klasse in der Ursprungs-Spec vertauscht und dann wollte es keiner gewesen sein und alle fanden es toll ;-) .


Horschdware - Fr 26.03.04 00:18

lol,
hab gerade ein bisschen rumexperimentiert und bin selber drauf gekommen. 8)

zur Erklärung: unser Infolehrer führt gerade Funktionen ein :roll:
da wollte er jetzt dann mal zeigen, was man mit funktionen NICHT machen kann.
mir kam das aber gleich irgendwie verdächtig vor. ich hatte irgendwie so das gefühl, dass das eben doch gehen muss.
und tatsach: das tut


Christian S. - Fr 26.03.04 00:56

@MaxiTB:

Meinst Du sowas?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
type
      TOuterClass = class
       strict private
          myField: Integer;
 
       public
          type
             TInnerClass = class
              public
                myInnerField: Integer;
                procedure innerProc;
             end;

         procedure outerProc;
       end;


In Delphi 8 geht das. :-)


MaxiTB - Fr 26.03.04 01:00

<--- Was steht den hier ... ? :P

PS: Jetzt wär ein Klugscheißer Tag nicht schlecht *g*.


Christian S. - Fr 26.03.04 01:16

Da steht "Dabei seit: 03.03.2003". :mrgreen:

Aber ich weiß schon, was Du meinst. ; -)


Udontknow - Fr 26.03.04 09:55

Hatte ich schon mal erwähnt, daß verschachtelte Funktionen/Prozeduren den Performance-Tod bewirken? Lasst sowas lieber sein.

Cu,
Udontknow


Sven - Fr 26.03.04 10:00

Udontknow hat folgendes geschrieben:
Hatte ich schon mal erwähnt, daß verschachtelte Funktionen/Prozeduren den Performance-Tod bewirken? Lasst sowas lieber sein.

Cu,
Udontknow


Wieso, weshalb, warum? Gibt es ein paar mehr Info's?


Udontknow - Fr 26.03.04 10:25

Hmmm.., Irgendwo hatte ich mal gelesen, daß da ineffizienter Code generiert wird, um die Parameter der äußeren Funktion der inneren zur Verfügung zu stellen. Allerdings kann ich gerade mit Beispielcode einen Performanceverlust nicht nachvollziehen... *grübel*...

Cu,
Udontknow


Sven - Fr 26.03.04 11:19

Udontknow hat folgendes geschrieben:
Hmmm.., Irgendwo hatte ich mal gelesen, daß da ineffizienter Code generiert wird, um die Parameter der äußeren Funktion der inneren zur Verfügung zu stellen. Allerdings kann ich gerade mit Beispielcode einen Performanceverlust nicht nachvollziehen... *grübel*...

Cu,
Udontknow


Wenn da wirklich ineffizienter Code bei rüberkommen sollte, wie sieht es denn dort mit den Funktionen aus, die ja auch auf Daten aus dem globalen Programmbereich zugreifen.
Also so ganz glauben tue ich das nicht.


catweasel - Fr 26.03.04 11:34

ich hab mir mal sagen lassen, dass in so einem Fall die Implementation der inneren Funktion beim compilieren jeden Aufruf in der äusseren ersetzt...
Also für...:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure aussen; 
  function innen :string
  var
  x : integer;
  begin
  Result := 'Eine Übersicht der natürlichen Zahlen von 1 bis 10 (sortiert): ');
  for x := 1 to 10 do  Result := Result+inttostr(x)+',');
  end;

begin 
 showmessage(innen);
showmessage('Und weils so schön war, gleich nochmal...');
 showmessage(innen);
end;


Könnte man auch :


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure alles;
var
 x : integer;
 temp : string;  // die Variable muss beispielsweise vom Compiler erzeugt werden.....
begin
 temp := 'Eine Übersicht der natürlichen Zahlen von 1 bis 10 (sortiert): ');
  for x := 1 to 10 do temp := temp+inttostr(x)+',');
showmessage(temp);

 temp := 'Eine Übersicht der natürlichen Zahlen von 1 bis 10 (sortiert): ');
  for x := 1 to 10 do temp := temp+inttostr(x)+',');
showmessage(temp);

end;


schreiben...
Das sieht schon verdächtig nach Ineffizienz aus..
Wie gesagt ich hab auch keine so ganaue Ahnung, aber so wurde es mir erklärt.. das es zu Redundanz im Code führen würde...
Und die Schleife in diesem Beispiel würde tatsächlich 2mal durchlaufen werden, da dieser tempwert aus irgendeinem Grund nicht gesichert werden kann.....
also ein

Delphi-Quelltext
1:
2:
showmessage(temp);
showmessage(temp);

würde hier "hinter den Kulissen" nicht erfolgen....

Catweasel

ps: Vielleicht macht sich das in einem Performancetest bemerkbar, wenn man das mal Übertreibt und so bis in eben 30-40 verschachtelt (mit vielen unterschiedlichen Parametertypen und so).... ;-) Vielleicht testet das ja mal wer...


Christian S. - Fr 26.03.04 11:46

Also das Beispiel ist irgendwie unsinnig. Logisch, dass es nicht effizient ist, wenn ich zweimal dieselbe Prozedur aufrufe. Aber das hat nichts damit zu tun, ob die Funktion verschachtelt ist.

Und wenn es so ist, dass verschachtelte Funktionen vom Compiler einfach den Funktionennamen durch die Funktion ersetzt, dann ist das sehr schnell. Nicht umsonst gibt man bei C++ das Wörtchen "inline" an oder arbeitet sogar mit #define, um kleine Prozeduren "direkt" an die entsprechenden Stellen zu schreiben.


Motzi - Fr 26.03.04 13:04

Udontknow hat folgendes geschrieben:
Hmmm.., Irgendwo hatte ich mal gelesen, daß da ineffizienter Code generiert wird, um die Parameter der äußeren Funktion der inneren zur Verfügung zu stellen. Allerdings kann ich gerade mit Beispielcode einen Performanceverlust nicht nachvollziehen... *grübel*...

Das stimmt nicht so ganz..!! Es müssen natürlich ein paar entsprechende "Manipulationen" am Stack vorgenommen werden um alle Variablen und Parameter auch in der Subroutine zur Verfügung zu stellen, allerdings kann man sich damit auch das Übergeben von Parametern an die Subroutine sparen..! Man kann das also nicht so verallgemeinern..

PS: Hagen hat dazu auch mal was in der Delphi-Praxis geschrieben...