Zuweisung von werten auf Out-Variablen

Zuviel Werbung?
-> Hier kostenlos registrieren
Neineinein ich bin noch nicht ganz einverstanden ...

Die Erklärung von WGertzen passt auf das beobachtete Phänomen, der Handbuchauszug aber nicht:
Achtung​
Wird in einem solchen Fall ein OUTPUT Parmeter in einem FC nicht beschrieben, können die ausgegebenen Werte zufällig sein! Der für die Kopie bereitgestellte Bereich in den Lokaldaten des rufenden Bausteins wird mangels Zuweisung an den OUTPUT Parmeter nicht beschrieben und bleibt somit unverändert. Damit wird zufällig der in diesem Bereich stehende Wert ausgegeben, da Lokaldaten nicht automatisch mit z. B. 0 vorbelegt sind.​
 
das erste mal, dass ich hier etwas dazu lerne.

aber schaut man sich den aufruf an, wirds auch deutlich. es ist kein darstellungsfehler, wie Perfektionist vermutet, sondern tatsächlichst so, wie von WGertzen beschrieben:

Code:
      UC    FC  1000
            P#E 0.0
            P#E 0.1
            P#E 0.2
            P#L 22.0
            P#L 24.0
            P#L 26.0
            P#M 10.0
            P#M 10.0
            P#M 10.0
      L     MW    10
      L     MW    10
      L     MW    10

wegen dem lehrgang: macht euch mal einen termin aus, ich komm dann gern vorbei und versohl euch den arsch.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Manchmal hat man ein Programm zu warten oder zu ändern, da denkt man sich : Das kann doch nie gelaufen haben.
Da das Programm aber trotzdem funktioniert, muss es ja eine Erklärung dafür geben und die hat WGertzen ja gefunden.

@forendiva
Ich kann Dir bestätigen, dass man hier in diesem Forum immer wieder was dazu lernen kann.
 
WGerzen hat Recht (und das Handbuch ist S......). Und ich stelle gerade fest, dass es zwei gleichlange Wörter gibt, die beide mit S beginnen, das eine mit s endet und das andere ein scharfes s enthält.

Mit dem Wissen von WGerzen ist folgendes Programm möglich:

OB1:
Code:
      CALL  FC     1
       in :=A0.0
       out:=E0.0

FC1:
Code:
FUNCTION FC 1 : VOID
TITLE =
VERSION : 0.1

VAR_INPUT
  in : BOOL ; 
END_VAR
VAR_OUTPUT
  out : BOOL ; 
END_VAR
BEGIN
NETWORK
TITLE =

      U     #out; 
      =     #in; 
 

END_FUNCTION

getestet und funktioniert ...
 
Das heißt also, die IN-Variablen sind auch IN-OUT-Variablen, die im aufgerufenen FC problemlos geändert werden können.
IN, OUT und IN/OUT sind demnach nur von der Deklaration her unterschiedlich, von der Programmabarbeitung her verhalten sie sich alle wie IN/OUT. In meinem Beispiel missbrauche ich einen IN-Parameter als OUT-Parameter und umgekehrt. Ich lese also im Code des FC den Wert von der Out-Variablen ein und gebe den Wert zur IN-Variablen zurück :twisted:
 
Letztendlich sind es alles Zeiger

Die Unterscheidung IN, OUT, IN-OUT ist eigentlich nur eine Information
für den Editor (FUP,KOP) damit er Schreibzugriffe auf IN Werte verhindern kann.
Letztendlich werden immer nur Zeiger übergeben.

Forendiva hatte es mit seinem Beispiel auch deutlich gemacht.
(Er hätte nur sagen sollen wie er den Quellcode erzeugt hatte ;-) )

Dazu über "erreichbare Teilnehmer" online gehen, den FC löschen und dann im OB1 (oder wo auch immer der FC aufgerufen wird) online gehen und den
Aufruf ansehen.

Dann steht dann so was wie:

Call
BLD 1
= L 25.0
UC FC 1
P#L 24.0
P#M 1200.0
P#M 1.1
BLD 2
End Call

Quelle war ein alter Eintrag aus dem Forum: (Danke an Raika)

RaiKa
29.02.2008, 12:22

Hallo Steve,

geh einfach mal in "erreichbare Teilnehmer", lösche die FC und schau den Aufruf der FC an.
 
Die Unterscheidung IN, OUT, IN-OUT ist eigentlich nur eine Information
für den Editor (FUP,KOP) damit er Schreibzugriffe auf IN Werte verhindern kann.
Letztendlich werden immer nur Zeiger übergeben.
...............
Das stimmt allerdings nur so lange man lediglich Eingänge, Ausgänge und Merker übergibt.
Bei Übergabe von Datenbausteinwerten sieht es dann doch ein wenig anders aus. Die Datenbausteinvariablen werden beim Aufruf des FC's in Temp's umkopiert und auf die Temp's dann erst mittels Zeiger zugegriffen.
Und dabei unterscheiden sich IN, OUT und IN_OUT dann doch voneinander.
Deshalb funktioniert der Test von Perfektionist mit Datenbausteinvariablen nicht.

Code:
      CALL  FC     2
       in :=DB4.DBX0.0
       out:=DB4.DBX0.1
sieht als letzendlicher Aufruf dann nämlich so aus:
Code:
 Call
      BLD   1
      =     L     20.0
      AUF   DB     4
      U     DBX    0.0
      =     L     20.1
      UC    FC     2
            P#L 20.1
            P#L 20.2
      U     L     20.2
      AUF   DB     4
      =     DBX    0.1
      BLD   2
      End Call
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Deshalb funktioniert der Test von Perfektionist mit Datenbausteinvariablen nicht.

von wegen, man muß nur wissen was man tut:

Code:
      AUF   DB   100
      BLD   1
      =     L     20.0
      UC    FC     2

            P#DBX 0.0
            P#DBX 0.1
      BLD   2

und wenn es zwei verschiedene sein sollen:

Code:
      AUF   DB   100
      AUF   DI   101

      BLD   1
      =     L     20.0
      UC    FC    16

            P#DBX 0.0
            P#DIX 0.1
      BLD   2
 
Sicher, wenn Du Funktionen üblicherweise so aufrufst....:rolleyes:

Und hast Du schon mal versucht das so im Editor einzugeben?:s3:
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Na dann bin ich zu Guter Letzt noch auf eine Lösung für folgenden Aufruf gespannt:

Code:
      CALL  FC     1
       in_1   :=DB4.DBX1.0
       in_2   :=DB5.DBX1.1
       out_1  :=DB6.DBX0.0
       out_2  :=DB7.DBX0.1
 
Na dann bin ich zu Guter Letzt noch auf eine Lösung für folgenden Aufruf gespannt:

Code:
      CALL  FC     1
       in_1   :=DB4.DBX1.0
       in_2   :=DB5.DBX1.1
       out_1  :=DB6.DBX0.0
       out_2  :=DB7.DBX0.1

ich hoffe, du erwartest nicht wirklich, dass irgendjemand sagt, die folgende lösung sei die schönste, die er je gesehen hätte. es soll nur veranschaulichen, dass, wenn man sich mal die mühe macht, hinter die kulissen des system zu schauen auch die einzelnen abläufe verstehen kann und somit auch zykluszeitoptimierungen durchführen kann ...

so siehts aus, wenn dem Perfektionist sein baustein noch funktionieren soll...

Code:
      AUF   DB     6
      AUF   DI     7

      BLD   1
      =     L     20.0
      UC    FC    16
            P#M 10.0


            P#M 10.1
            P#DBX 0.0
            P#DIX 0.1
      BLD   2
      U     M     10.0
      AUF   DB     4
      =     DBX    1.0
      U     M     10.1
      AUF   DB     5
      =     DBX    1.1

editierbar:

Code:
      AUF   DB     6
      AUF   DI     7

      CALL  FC    16
       in1 :=M10.0
       in2 :=M10.1
       out1:=DBX0.0
       out2:=DIX0.1


      U     M     10.0
      =     DB4.DBX    1.0
      U     M     10.1
      =     DB5.DBX    1.1
 
Sei es wie es sei, eigentlich wollte ich mit diesem_Beitrag lediglich dem geschmähten Handbuch Gerechtigkeit widerfahren lassen.
WGerzen hat Recht (und das Handbuch ist S......). Und ich stelle gerade fest, dass es zwei gleichlange Wörter gibt, die beide mit S beginnen, das eine mit s endet und das andere ein scharfes s enthält.
............

Denn die Aussage im Handbuch hierzu ist doch völlig korrekt:
Funktionen (FC) haben kein Gedächtnis. Die Versorgung der Formalparameter ist deshalb im Gegensatz zum FB nicht optional, sondern zwingend erforderlich. Der Zugriff auf FC-Parameter erfolgt über Adressen (bereichsübergreifende Zeiger).
Wird als Aktualparameter ein Operand aus dem Bereich Daten (Datenbaustein) oder eine lokale Variable des rufenden Bausteins verwendet, wird für die Parameterübergabe eine Kopie des Aktualparameters in den Lokaldaten des rufenden Bausteins temporär gespeichert.
Achtung
Wird in einem solchen Fall ein OUTPUT Parmeter in einem FC nicht beschrieben, können die ausgegebenen Werte zufällig sein!
Der für die Kopie bereitgestellte Bereich in den Lokaldaten des rufenden Bausteins wird mangels Zuweisung an den OUTPUT Parmeter nicht beschrieben und bleibt somit unverändert. Damit wird zufällig der in diesem Bereich stehende Wert ausgegeben, da Lokaldaten nicht automatisch mit z. B. 0 vorbelegt sind.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
...die Aussage im Handbuch hierzu ist doch völlig korrekt:
...
ich gebe zu, zu dem Zeitpunkt, als ich das Handbuch schmähte, habe ich weder das Handbuch vollständig verstanden noch den Sachverhalt, der hier dahinter steht.

Wobei ich folgende Aussage(n) nach wie vor als missverständlich empfinde:
... für die Parameterübergabe [wird] eine Kopie des Aktualparameters in den Lokaldaten des rufenden Bausteins temporär gespeichert.
Wenn es sich bei der Rückgabe eines OUT-Parameters um eine Parameterübergabe handelt, so wird eben NICHT eine Kopie des Aktualparameters erzeugt, sondern nur ein Platz für die Rückgabe reserviert.

Folgerichtig müsste für mich der Satz
Der für die Kopie bereitgestellte Bereich ... wird mangels Zuweisung ... nicht beschrieben
also lauten:
Der für die Rückgabe des OUT-Parameters bereitgestellte Bereich ... wird mangels Zuweisung ... nicht beschrieben

nun ja, man wird mich wohl jetzt für spitzfindig halten - wobei ich solche Threads doch sehr geniesse ;)
 
Zurück
Oben