-
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
-
Hallo Dieter,
innerhalb einer Prozedur brauchst du kein *INLR.
Die Variablen werden bei jeden Aufruf automatisch initialisiert.
Zitat von dschroeder
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
-
... 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
-
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
-
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
-
... 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
-
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
-
...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
-
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.
-
-
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
-
Vielen Dank für alle Antworten.
Das, was Birgitta sagt, deckt sich mit meinen Erfahrungen.
Dieter.
Similar Threads
-
By hartmuth in forum NEWSboard Programmierung
Antworten: 3
Letzter Beitrag: 18-09-14, 09:57
-
By SourceCoder in forum NEWSboard Programmierung
Antworten: 1
Letzter Beitrag: 03-04-14, 11:22
-
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
-
Foren-Regeln
|
Erweiterte Foren Suche
Google Foren Suche
Forum & Artikel Update eMail
AS/400 / IBM i
Server Expert Gruppen
Unternehmens IT
|
Kategorien online Artikel
- Big Data, Analytics, BI, MIS
- Cloud, Social Media, Devices
- DMS, Archivierung, Druck
- ERP + Add-ons, Business Software
- Hochverfügbarkeit
- Human Resources, Personal
- IBM Announcements
- IT-Karikaturen
- Leitartikel
- Load`n`go
- Messen, Veranstaltungen
- NEWSolutions Dossiers
- Programmierung
- Security
- Software Development + Change Mgmt.
- Solutions & Provider
- Speicher – Storage
- Strategische Berichte
- Systemmanagement
- Tools, Hot-Tips
Auf dem Laufenden bleiben
|
Bookmarks