Unbekannter Variabeltyp

Beiträge
226
Reaktionspunkte
27
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen

Bin gerade an einer Funktion dran, die unter Anderem eine Plausibilitätsprüfung von Variabelwerten durchführen soll.
Die Funktion hat einige Eingangsparameter, auch solche für genau diese Plausibilitätsprüfung.
Leider weiss ich ja jetzt noch nicht, welchen Variabeltyp der Baustein dann effektiv vergleichen muss.
Hängt ganz von der Anwendung ab.

So wäre es doch schön, wenn der Eingangsparameter im Typ undefiniert wäre. Aber sowas in der Art von Object kenn ich von CoDeSys nicht.

Da erliegt man doch Glatt der Versuchung, den MEMORYCMP einzusetzen, die Eingangsparameter als Word zu deklarieren und dem Bausteinbenutzer
halt vorzugeben seine Eingänge als ADR(Variabelname) zu deklarieren und die vom Typ abhängige Speichergrösse anzugeben (Int = 2, Real = 4 usw).

Würde ja eigentlich funktionieren. Nur kann ich ja dann die Prüfvariabel nicht mit dem Grenzwert überschreiben. Was in dieser Plausibilitätsprüfung eigentlich vorgesehen wäre.

Hat jemand noch eine Idee, wie sowas realisiert werden könnte?


Grüsse
 
Kommt drauf an welche Codesys Version du verwendest. Ich weiß nicht ob die aktuelle Version mit Objektorientierung sowas wie Funktionsüberladung kennt. Bei den 2.x Versionen gibt es sowas für eigene Funktionen zumindest nicht.

Dein konkreter Anwendungsfall hört sich doch nach der Verwendung von LIMIT() an. Das ist eine integrierte Funktion die mit allen numerischen Typen arbeitet (ANY_NUM). Wobei ich schätze dass es kein echter Funktionsaufruf ist, sondern ein Makro was während des Compilier-Vorganges je nach Datentyp der Parameter eingesetzt wird.

Der Siemens-Any Pointer ist eigentlich das was du selber programmieren willst. Nur dass dort der Zeiger und der Datentyp zusammengesetzt sind. Der einzige Vorteil beim S7 Any-Pointer ist der, dass wenn man symbolisch programmiert dieser automatisch den richtigen Datentyp enthält (Siemens kennt aber auch nicht so viele Typen wie Codesys).

Falls du bei deiner Auswertung einen Wert nur auf 0 setzen willst, könntest du am Speichergrößen-Eingang auch den Sizeof() Operator verwenden, da die 0 bei allen numerischen Datentypen gleich aussieht.

Ob das unbedingt sinnvoll ist wenn man die Typüberprüfung des Compilers durch die Verwendung von Zeigern aufgibt ist eine andere Frage.
 
Ja es ist die 2er Version. Da gibt es noch keine Möglichkeit Überladungen zu schreiben.


Ob das unbedingt sinnvoll ist wenn man die Typüberprüfung des Compilers durch die Verwendung von Zeigern aufgibt ist eine andere Frage.

Hast schon recht. LIMIT ist die Funktion welche in meiner Funktion aufgerufen wird. Aaaber,
ich muss die LIMIT-Funktion ja auch mit Variabeln füttern, und die kämen aus der Schnittstelle meiner eigenen Funktion.
Und da ist nun die Problematik der Typbestimmung. Prinzipiell geht es echt nur um die Schnittstelle. Den Vergleich macht
mir ja dann die LIMIT-Funktion.

Ich dachte nur am MEMORYCMP da ich dort die Adresse als Schnittstelle übernehmen könnte
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Da gibt es wohl keine elegante Lösung. Also entweder eine eigene Funktion für jeden Datentyp, oder einen FB mit eigenen INPUT-/OUTPUT-Variablen und einer eigenen Aufruf-Aktion für jeden Typ. Nur für die Grenzwerte reicht dann eine Variable vom Datentyp mit dem grössten Wertebereich. Die notwendigen Typumwandlungen kann man dann in die Aktionen packen.
 
... jetzt bin ich aber enttäuscht ... es gibt keinen ANY oder ein Pendant dazu ...!?
In dem Fall käme der (etwas unelegante) Vorschlag von ST allerdings einer Überladung noch am Nächsten ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Nein ... habe ich nicht - ganz im Gegenteil.
In der Siemens-Welt geht es halt nur nicht und in (zumindestens deiner) Codesys-Welt anscheinend auch nicht.
Den Vorschlag von ST habe ich so aufgenommen, dass er einen Baustein macht mit mehreren unterschiedlichen Input-Variablen von denen die jeweils beschaltete weiterverwendet wird - das ist nur eine Pseudo-Überladung (leider).

Gruß
Larry
 
Nein ... habe ich nicht - ganz im Gegenteil.
In der Siemens-Welt geht es halt nur nicht und in (zumindestens deiner) Codesys-Welt anscheinend auch nicht.
Den Vorschlag von ST habe ich so aufgenommen, dass er einen Baustein macht mit mehreren unterschiedlichen Input-Variablen von denen die jeweils beschaltete weiterverwendet wird - das ist nur eine Pseudo-Überladung (leider).

Gruß
Larry
Ja, so war es gemeint. Schön ist das natürlich nicht, da möchte man sich eher übergeben statt überladen. Ich tendiere bei solchen Sachen doch eher zu einzelnen Funktionen für jeden Datentyp. In CoDeSys 3 wird es auch nicht gehen. Man kann zwar vererbte Methoden ersetzen, ihnen aber keine anderen Input-Variablen verpassen. Immerhin soll es möglich werden, ANY_TYPE- und ANY_NUM-Variablen als Input-Parameter an Funktionen zu übergeben, in der Version 3.4 ist das aber auch noch nicht umgesetzt.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich tendiere bei solchen Sachen doch eher zu einzelnen Funktionen für jeden Datentyp.

Vom Aufwand her meine ich plausibel. Man müsste, sofern man es mit nur einem Baustein machen möchte
ja eh auch für alle Datentypen den Vergleich schreiben.

Man kann zwar vererbte Methoden ersetzen, ihnen aber keine anderen Input-Variablen verpassen.

Klingt für mich irgendwie nach einer halbfertigen Lösung und ist ja eigentlich auch nur eine Pseudo-Überladung (frei nach Larry :p )
Ok man kann die Funktion alität anpassen, aber eigentlich kenne ich zwischen 0 und 0 Anwendungen bei denen ich Überladungen mit gleicher Schnittstelle gemacht habe.
Ja gut vielleicht die Sonderfälle aus (VB).Net wie New, BeginInit usw.....
Aber nicht bei eigenen Funktionen/Prozeduren.


Immerhin soll es möglich werden, ANY_TYPE- und ANY_NUM-Variablen als Input-Parameter an Funktionen zu übergeben, in der Version 3.4 ist das aber auch noch nicht umgesetzt.

Jep. Mit Betonung auf....
 
Also zunächst mal: die Norm kennt zwar diese ANY-Datentypen, diese sind aber nicht zum Programmieren gedacht.
Die werden für die Zwecke der Norm benutzt. Die Norm kennt prinzipiell nur bei den Standardoperatoren "Überladungen" und das wird selbst
mit der nächsten Version noch so bleiben.
Der Grund ist relativ einfach: es ist sauschwer, ordentliche Regeln zu formulieren, wie Überladung funktionieren soll.
Was für eine Überladung soll aufgerufen werden für fun(1)? BOOL, WORD, INT, DINT? für fun(-1)? für fun(0)?
Das ist ziemlich fehlerträchtig. Wenn man aber fordert fun(BOOL#1) zu schreiben, was ist dann gewonnen gegenüber
fun_BOOL(1)?
Also ich bin dafür immer ordentlich hinzuschreiben, welche Funktion man vorhat aufzurufen, das hält einem viel Ärger vom Leib.

Bernhard
 
Also zunächst mal: die Norm kennt zwar diese ANY-Datentypen, diese sind aber nicht zum Programmieren gedacht.
Die werden für die Zwecke der Norm benutzt. Die Norm kennt prinzipiell nur bei den Standardoperatoren "Überladungen" und das wird selbst
mit der nächsten Version noch so bleiben.
Der Grund ist relativ einfach: es ist sauschwer, ordentliche Regeln zu formulieren, wie Überladung funktionieren soll.
Was für eine Überladung soll aufgerufen werden für fun(1)? BOOL, WORD, INT, DINT? für fun(-1)? für fun(0)?
Das ist ziemlich fehlerträchtig. Wenn man aber fordert fun(BOOL#1) zu schreiben, was ist dann gewonnen gegenüber
fun_BOOL(1)?

In C++ wird anhand der Signatur entschieden welche Funktion letztendlich aufgerufen wird, die Regeln sind meine ich auch klar. Wie man an diversen Funktionen wie z.B. auch LIMIT() sieht, scheint diese grundsätzliche Funktion in Codesys also schon vorhanden zu sein. Oder läuft es bei diesem Funktionen anders ab?

Ich denke nicht dass gefordert ist, den Variablentyp während der Laufzeit des Systems ändern zu können, denn dazu müsste man den Typ immer mitführen. Bei Siemens wäre das sogar möglich, da in dem S7-ANY der Typ mitgeführt wird. (auch wenn er zur Compile-Zeit festgelegt wird wenn man symbolisch programmiert).
 
Zuviel Werbung?
-> Hier kostenlos registrieren
In C++ wird anhand der Signatur entschieden welche Funktion letztendlich aufgerufen wird, die Regeln sind meine ich auch klar. Wie man an diversen Funktionen wie z.B. auch LIMIT() sieht, scheint diese grundsätzliche Funktion in Codesys also schon vorhanden zu sein. Oder läuft es bei diesem Funktionen anders ab?
Ja das läuft anders ab. Der Compiler kennt die Funktion LIMIT (und die anderen Operatoren) und behandelt die speziell. Und auch bei den impliziten Funktionen gibt es immer wieder Probleme, wie etwa
bei word := ROL(1, 17);
Häufig wird eine Operation nicht so ausgeführt wie der Programmierer sich das denkt, dabei machen immer die nichtgetypten Literale Probleme, vor allem dann noch in einem komplexen Ausdruck mit
unterschiedlichen anderen Typen.

Ich weiss, wie das C++ macht, auch da kommen seltsame Sachen dabei raus. Und natürlich ist das auch in C++ eine Fehlerquelle. Gerade durch Vererbung passiert es häufig dass die Basisimplementierung einer Funktion geändert wird, wodurch die Ableitung plötzlich nicht mehr überschreibt, sondern überlädt.
Natürlich ist das manchmal praktisch, aber es ist schwer zu implementieren, schwer zu beherrschen, fehlerträchtig und bietet keinen echten Mehrwert.
Für die Stringfunktionen haben wir beispielsweise auch keine Überladung definiert, und bis jetzt hat sich noch keiner beschwert dass er einmal CONCAT und einmal WCONCAT schreiben muss.

Bernhard
 
Für die Stringfunktionen haben wir beispielsweise auch keine Überladung definiert, und bis jetzt hat sich noch keiner beschwert dass er einmal CONCAT und einmal WCONCAT schreiben muss.


Was für eine Überladung soll aufgerufen werden für fun(1)?

So gesehen hast Du natürlich recht. Ursprünglich ging es ja darum, einen unbekannten Datentyp in einer Schnittstelle zu verwenden.
Selbst wenn es die Möglichkeit gäbe, saubere Überladungen zu schreiben, müsste auch eine Überladung für jeden möglichen Datentyp
erstellt werden. Sprich man hätte einen vergleichbaren Aufwand, wie wenn die Funktion für jeden Datentyp separat erstellt wird.
Okay, der Aufruf hiesse zumindest immer gleich, aber wie Du schon sagst, mann kann sie ja x_fun, oder di_fun, oder wie auch immer nennen.

Das Bedürfnis während der Laufzeit einen Variabeltyp zu ändern habe ich bislang noch nicht verspürt:)

Gruss
 
Zurück
Oben