Oder andersherum gefragt - wie kommt der Funktionsbaustein an einen Stack? Das kann er doch nur über eine Task, sprich, wenn eine (z.B. globale) Funktion eine lokale Instanz (also auf dem Stack des aufrufenden Threads) einer Klasse erzeugt, die dann eine (Member-) Funktion enthält, welche Ihrerseits eine VAR_INST-Deklaration beinhaltet. Nur in diesem Fall läge die VAR_INST Variable dann tatsächlich auf einem Stack (des aufrufenden Thread/der aufrufenden Task)?!
Kann mir hier jemand auf die Sprünge helfen?
PS: Ich komme aus der C/C++ Ecke und tue mich mit solchen Termini leichter
Schöne Grüße
schnasseldag
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Mittels eines kleinen Beispiels habe ich mir die Frage nun selbst beantwortet.
VAR_INST deklarierte Variable teilen sich den Speicherbereich mit den (Member-) Variablen der Objektinstanz (innerhalb derer die (Member-) Funktion deklariert ist). Von Ihrer Sichtbarkeit (Scope) her sind sie jedoch auf die der (Member-) Funktion beschränkt. Deklarieren mehrere (Member-) Funktionen Variablen desselben Namens, so werden für jede Variablendeklaration auch einzelne Speicherbereiche in der Objektinstanz erzeugt (vermutlich durch das Namemangling des Compilers).
Überprüft habe ich dies durch einen Wertevergleich einer echten Stackvariable (VAR_INPUT innerhalb einer Funktion ) und einer VAR_INST-Variable nach einigen rekursiven Aufrufen der Funktion . Währenddessen die Stackvariable für jeden Funktionsaufruf einen anderen Wert besitzt, wird die VAR_INST Variable (weil "global" in der Objekinstanz) immer wieder überschrieben. Anbei der Code:
METHODPUBLICfoo : INTVAR_INPUT
  count : INT;END_VARVAR_INST
  test_count : INT :=0;  END_VARtest_count :=count;IF(count>0)THEN
  THIS^.foo(count-1);END_IFIF(count=test_count)AND(count>0)THEN
  bIsStackVariable :=TRUE; // test_count ist eine Stack-Variable
  ELSE
    bIsStackVariable :=FALSE; // test_count ist eine Objekt-Variable
  END_IF//Wasliefertunsnuntest_count_countderFunktionfoo2()?
foo :=foo2();//foo2()liefertimmer42fürderentest_countVariablezurück.
//DamitwirdinderFB1-InstanzoffenbareineweitereSpeicherstelleallociert.
//VomCompilerscheintdaswohlperNamemanglingderArt"FB_foo_test_count"bzw."FB_foo2_test_count"o.ä. gelöstzusein?!Â
liefert brav 42 zurück. Deren Variable "kollidiert" also nicht mit der aus der Funktion .
METHODPUBLICfoo2:INTVAR_INST  test_count:INT:=42;  END_VAR//Greifenfoo2()undfoo()aufdiegleicheVariableinnerhalbdesFB1zu?foo2:=test_count;//Antwort:Nein.DerCompilererzeugtfürbeidelokalenVariableneineneigenenSpeicherbereichimFB1-Objekt.
Im Anhang befindet sich der vollständige Testcode.
Hallo miteinander,
https://help.codesys.com/webapp/cds-vartypes-var-inst;product=codesys;version=3.5.11.0
Oder andersherum gefragt - wie kommt der Funktionsbaustein an einen Stack? Das kann er doch nur über eine Task, sprich, wenn eine (z.B. globale) Funktion eine lokale Instanz (also auf dem Stack des aufrufenden Threads) einer Klasse erzeugt, die dann eine (Member-) Funktion enthält, welche Ihrerseits eine VAR_INST-Deklaration beinhaltet. Nur in diesem Fall läge die VAR_INST Variable dann tatsächlich auf einem Stack (des aufrufenden Thread/der aufrufenden Task)?!
Kann mir hier jemand auf die Sprünge helfen?
PS: Ich komme aus der C/C++ Ecke und tue mich mit solchen Termini leichter
Schöne Grüße
schnasseldag
Mittels eines kleinen Beispiels habe ich mir die Frage nun selbst beantwortet.
VAR_INST deklarierte Variable teilen sich den Speicherbereich mit den (Member-) Variablen der Objektinstanz (innerhalb derer die (Member-) Funktion deklariert ist). Von Ihrer Sichtbarkeit (Scope) her sind sie jedoch auf die der (Member-) Funktion beschränkt. Deklarieren mehrere (Member-) Funktionen Variablen desselben Namens, so werden für jede Variablendeklaration auch einzelne Speicherbereiche in der Objektinstanz erzeugt (vermutlich durch das Namemangling des Compilers).
Überprüft habe ich dies durch einen Wertevergleich einer echten Stackvariable (VAR_INPUT innerhalb einer Funktion ) und einer VAR_INST-Variable nach einigen rekursiven Aufrufen der Funktion . Währenddessen die Stackvariable für jeden Funktionsaufruf einen anderen Wert besitzt, wird die VAR_INST Variable (weil "global" in der Objekinstanz) immer wieder überschrieben. Anbei der Code:
liefert brav 42 zurück. Deren Variable "kollidiert" also nicht mit der aus der Funktion .
Im Anhang befindet sich der vollständige Testcode.
VarInst.zip [375.75 KiB]