[NEWSboard IBMi Forum]
Seite 1 von 2 1 2 Letzte
  1. #1
    Registriert seit
    Jan 2012
    Beiträge
    1.120

    Lebensdauer von static Variablen

    Hallo,
    ich bin auf eine Merkwürdigkeit gestoßen und möchte nur wissen, ob ich das richtig verstanden habe:
    Ich habe ein RPG-Programm, das auch eine Procedure enthält. Z.B:
    Code:
           
    dcl-s i packed(5) inz(23);
    
    i+=1;
    dsply %char(i);
    
    test2();
    
    *inlr = *on;
    //================================
    dcl-proc test2;
    
    dcl-s wert2 packed(2) static;
    
    wert2 +=1;
    
    dsply %char(wert2);
    
    end-proc;
    Wenn ich das Programm mehrfach aufrufe, wird die globale Variable i bei jedem Aufruf immer wieder mit dem INZ-Wert 23 initialisiert. Das funktioniert (ist ja klar, da das Programm mit *INLR=*ON verlassen wird). In der Procedure test2 wird die Variable wert2 als static definiert. Diese Variable behält allerdings ihren Wert auch über das Verlassen des Programms hinaus! Dieses Verhalten hätte ich nur erwartet, wenn ich das Programm ohne LR verlassen hätte.

    Das heißt, dass lokale static Variablen länger leben als globale Variablen! Das finde ich sehr merkwürdig.

    Im Handbuch steht "If the keyword STATIC is specified, the item will be initialized at module initialization time."

    Wann ist denn die "module initialization time" ?

    Dieter

  2. #2
    Registriert seit
    Aug 2003
    Beiträge
    1.508
    Hallo Dieter,

    innerhalb einer Prozedur brauchst du kein *INLR.
    Die Variablen werden bei jeden Aufruf automatisch initialisiert.
    Zitat Zitat von dschroeder Beitrag anzeigen
    Wann ist denn die "module initialization time" ?
    Wenn das Modul geladen wird (Programmstart) oder beim ersten Aufruf einer Prozedur die sich in diesem Modul befindet. Da bin ich mir jetzt nich ganz sicher.

    Mit STATIC kann man viel pfusch betreiben. Deshalb vermeide ich diese besser.

    lg Andreas

  3. #3
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    ... das ist auf Seite 119 (Abteilung Pathologie) der RPG Reference so beschrieben:
    "Static storage in the main procedure is subject to the RPG cycle, and so the value
    changes on the next call if LR was on at the end of the last call. However, local
    static variables will not get reinitialized because of LR in the main procedure."

    D*B
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  4. #4
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Hallo Andreas,
    mir ist schon klar, dass ich in einer Procedure kein LR brauche und dass Variablen automatisch initialisiert werden.
    In meinem echten Problem wollte ich eine Warnmeldung implementieren. Die Procedure, die ggf. die Meldung ausgibt, soll sich merken, ob die Warnung schon mal ausgegeben wurde. Dazu würde ich gerne static benutzen. Natürlich soll eine static Variable ihren Wert über die Lebensdauert der Procedure hinaus erhalten (sonst wäre static ja sinnlos). Aber ich fände es naheliegend, wenn die Lebensdauer nicht über die Lebensdauer des Programm, in dem sich die Procedure befindet, hinausgehen würde. Wenn ich das Programm mit LR beende, werden ja sogar alle globalen Variablen des Programms initialisiert. Nur die static Variablen in einer innenliegenden Procedure nicht!

    Das finde ich nicht richtig.
    Dieter

  5. #5
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Hallo Dieter,
    vielen Dank. Den Text hatte ich auch schon gelesen. Ist schon wahr, da steht, dass LR auf static Variablen nicht wirkt. Aber direkt davor steht "If the keyword STATIC is specified, the item will beinitialized at module initialization time.". Deshalb die Frage: Was ist denn genau der "module initialization" Zeitpunkt?
    Dieter

  6. #6
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    ... auch das steht in der Reference, auf Seite 98:
    "First time
    subprocedure
    has been called?"
    "Initialize static variables"

    Man beachte den feinsinnigen Unterschied:
    - static Variablen werden beim anlegen initialisiert
    - LR initialisiert die globalen Variablen beim verlassen des Programms

    Vom Design her ist das mit dem static local frei nach Fred Feuerstein Dummfug der dummfugigsten Sorte, mit Zustand behaftete Variablen gehören global definiert (damit das Modul seinen eigenen Zustand kennt) alles andere verhindert Modularisierung!

    D*B
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  7. #7
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Danke für die Info. Wenn ich mir eine Implementierung wünsche könnte, würde ich die statischen Variablen ebenfalls mit LR initialisieren. Dann würden sie sich genauso wie globale Variablen verhalten. Dann würde static Sinn machen. So macht es auch für mich keinen Sinn.
    (Ich spreche hier nur von Variablen, die in internen (nicht exportierten) Procedures definiert sind).

    Dieter

  8. #8
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    ...der Haken an der Sache beginnt da, wo so eine Procedure wächst und es sinnvoll wird sie zu teilen, dann muss man die lokale static Variable als Parameter durchschleifen, was dazu führt, dass weitere Modularisierung komplizierter wird oder sogar unterbleibt. Wenn ein Modul zu viele Zustandsgrößen (sprich globale Variablen hat), dann ist es zu groß!

    D*B
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  9. #9
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Bzgl. STATIC muss man allerdings den Kontext sehen.

    Wenn ein Prozedur mit Return verlassen wird, bleibt eine STATIC-Variable mit ihrem Inhalt bestehen.
    Wenn das Programm mit Return (oder automatisch am Ende) mit LR *on verlassen wird, wird das Programm aus der ACTGRP deaktiviert und entfernt.
    Beim nächsten CALL wird das Programm neu initialisiert und somit auch alle Static's in allen Modulen die vorkommen.
    Auch die *INZSR-Subroutine (falls vorhanden) wird erneut aufgerufen.
    An diesem Verhalten hat sich nichts geändert.

    Die Doku geht da etwas schwammig damit um, da sie sich nur auf Module bezieht.
    Aber ein Modul muss die Startprozedur enthalten, die für das LR zum Beenden entscheidend ist.

    LR = *ON initialisiert keine Variablen sondern entscheidet beim Return, ob Dateien geschlossen und Locks aufgehoben werden.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  10. #10
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    ... simply wrong!
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  11. #11
    Registriert seit
    Aug 2001
    Beiträge
    2.873
    Ich denke die Dokumentatin ist eindeutig:
    1. Nur echte Main-Procedures (alle Statements vor dem ersten P-Statement) unterliegen dem RPG-Zyklus.
    Der RPG-Zyklus wird immer integriert, auch dann wenn Dateien nicht mit IP oder UP definiert und verarbeitet werden.
    Variablen, die in den globalen D-Bestimmungen definiert werden, gehören zu der Main-Procedure und können somit mit und durch den RPG-Zyklus gesteuert werden.
    Wird eine Main-Procedure mit LR beendet, werden alle Variablen, die in der Main-Procedure definiert wurden beim nächsten Aufruf initialisiert. (So war es schon immer und das wurde nicht geändert)

    2. Wird eine Main-Procedure mit RETURN (ohne LR) beendet, werden in der Main-Procedure definierten Variablen beim nächsten Aufruf nicht initialisiert, sofern der Aufruf in der gleichen Aktivierungsgruppe erfolgt.
    Die in der Main-Procedure definierten Variablen werden immer beim ersten Aufruf innerhalb einer Aktivierungsgruppe initialisiert.
    Da die Main-Procedure dem Zyklus unterliegt kann der Zyklus auch die Initalisierung der Variablen steuern.
    (Das wurde seit Einführung von ILE so gehandelt!)

    3. Procedures unabhängig davon, ob nur intern definiert oder exportiert oder als lineare Main-Procedures hinterlegt, unterliegen nicht dem Zyklus und folglich kann auch der Zyklus die Initialisierung der Variablen (weder der "normalen" lokalen, noch der statischen lokalen) nicht steuern.
    Die Initialisierung der statischen Variablen hängt von der Aktivierungsgruppe ab, d.h. nur beim ersten Aufrfu innerhalb einer Aktivierungsgruppe werden die Variablen initialisiert. Alles andere muss manuell (im Programm-Code) gehandelt werden.

    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  12. #12
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Vielen Dank für alle Antworten.
    Das, was Birgitta sagt, deckt sich mit meinen Erfahrungen.

    Dieter.

Similar Threads

  1. Anzahl der Host-Variablen geringer als die Ergebniswerte
    By hartmuth in forum NEWSboard Programmierung
    Antworten: 3
    Letzter Beitrag: 18-09-14, 09:57
  2. Begrenzung im Debugger bei der Anzeige von Variablen erhöhen?
    By SourceCoder in forum NEWSboard Programmierung
    Antworten: 1
    Letzter Beitrag: 03-04-14, 11:22
  3. CL Variablen konvertieren
    By danielfeurstein in forum IBM i Hauptforum
    Antworten: 4
    Letzter Beitrag: 22-07-02, 15:19

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • You may not post attachments
  • You may not edit your posts
  •