In CODESYS ist es prinzipiell erlaubt, den gleichen Bezeichner für verschiedene Elemente zu verwenden. So können beispielsweise ein Baustein und eine Variable gleich benannt werden. Um Verwechslungen vorzubeugen, sollte dies jedoch vermieden werden.
Negativbeispiel: Im folgenden Codeausschnitt hat eine lokale Funktionsbaustein-Instanz den gleichen Namen wie eine Funktion:
Beispiel
FUNCTION YYY : INT ; END_FUNCTION FUNCTION_BLOCK XXX ; END_FUNCTION_BLOCK PROGRAM PLC_PRG VAR YYY : XXX; END_VAR YYY(); END_PROGRAM
In einem solchen Fall ist unklar, ob im Programm die Instanz oder die Funktion aufgerufen wird.
Um sicherzustellen, dass Namen immer eindeutig sind, sollten Namenskonventionen beachtet werden, beispielsweise bestimmte Präfixe für Variablen. Regeln für die Bezeichnervergabe finden Sie im Hilfekapitel "Bezeichner".
Namenskonventionen können mit Hilfe der statischen Codeanalyse von CODESYS automatisch überprüft werden. Die statische Codeanalyse könnte auch die doppelte
Verwendung des Namens YYY
aufdecken und als Fehler melden.
Auch durch die konsequente Verwendung des Attributs qualified_only
für Enumerationen und globale Variablenlisten und durch die Verwendung von qualifizierten
Bibliotheken können nicht-eindeutige Situationen vermieden werden.
Um sicherzustellen, dass beim Aufruf eines Programmierbausteins der Ansicht „POUs“ nicht ein gleichnamiger Programmierbaustein der Ansicht „Geräte“ aufgerufen wird, sollte beim Aufruf dem Namen des Programmierbausteins der Operator
__POOL
vorangestellt werden, beispielsweise svar_pou := __POOL.POU();
Verschattung: Der Compiler meldet grundsätzlich weder Fehler noch Warnungen, wenn derselbe Bezeichner für verschiedene Elemente verwendet wird. Stattdessen durchsucht der Compiler den Code in einer bestimmten Reihenfolge nach der Deklaration des Bezeichners. Wenn eine Deklaration gefunden wurde, dann sucht der Compiler nicht nach eventuellen weiteren Deklarationen an anderer Stelle. Wenn weitere Deklarationen existieren, dann sind diese für den Compiler „verschattet“. Im Folgenden werden die Verschattungsregeln beschrieben, das heißt die Suchreihenfolgen , die der Compiler bei der Suche nach der Deklaration für Bezeichner verwendet. Im Abschnitt "Uneindeutige Zugriffe und qualifizierte Zugriffe" werden Möglichkeiten aufgezeigt, um uneindeutige Zugriffe zu vermeiden und die Verschattungsregeln zu umgehen.
Suchreihenfolge in der Applikation
Wenn der Compiler im Code einer Applikation auf einen einzelnen Bezeichner trifft, dann sucht er die zugehörige Deklaration in der folgenden Reihenfolge:
1. Lokale Variablen einer Methode
2. Lokale Variablen im Funktionsbaustein, Programm oder Funktion und in eventuellen Basisfunktionsbausteinen
3. Lokale Methoden des Bausteins
4. Globale Variablen in der Applikation, wenn in der Variablenliste, in der die globalen
Variablen deklariert sind, nicht das Attribut qualified_only
gesetzt ist
5. Globale Variablen in einer Vaterapplikation, sofern in der Variablenliste, in der
die globalen Variablen deklariert sind, nicht das Attribut qualified_only
gesetzt ist
6. Globale Variablen in angezogenen Bibliotheken, wenn weder die Bibliothek noch die Variablenliste qualifizierten Zugriff erfordert
7. Baustein- oder Typnamen aus der Applikation (das heißt: Namen von Globalen Variablenlisten, Funktionsbausteinen etc.)
8. Baustein- oder Typnamen aus einer Vaterapplikation
9. Baustein- oder Typnamen aus einer Bibliothek
10. Namensräume von lokal angezogenen Bibliotheken und Bibliotheken, die von Bibliotheken veröffentlicht werden
11. Globale Variablen in der Ansicht „POUs“, sofern in der Variablenliste, in der sie deklariert sind, nicht das Attribut qualified_only
gesetzt ist
12. Baustein- oder Typnamen aus der Ansicht „POUs“ (das heißt: Namen von Globalen Variablenlisten, Funktionsbausteinen etc.)
Bibliotheken, die im Bibliotheksverwalter der Ansicht „POUs“ eingefügt werden, werden mit der entsprechenden Platzhalterauflösung in den Bibliotheksverwalter in allen Applikationen im Projekt gespiegelt. Diese Bibliotheken bilden dann mit den Bibliotheken in der Applikation einen gemeinsamen Namensraum. Daher gibt es keine Verschattung von Bibliotheken im Pool durch Bibliotheken in der Applikation.
Suchreihenfolge in der Bibliothek
Wenn der Compiler im Code einer Bibliothek auf einen einzelnen Bezeichner trifft, dann sucht er die zugehörige Deklaration in der folgenden Reihenfolge:
1. Lokale Variablen einer Methode
2. Lokale Variablen im Funktionsbaustein, Programm oder Funktion und in eventuellen Basis-Funktionsbausteinen
3. Lokale Methoden des Bausteins
4. Globale Variablen in der lokalen Bibliothek, wenn die Variablenliste, in der die
globalen Variablen deklariert sind, nicht das Attribut qualified_only
gesetzt hat
5. Globale Variablen in angezogenen Bibliotheken, wenn weder die Bibliothek noch die Variablenliste qualifizierten Zugriff erfordert
6. Baustein- oder Typnamen aus der lokalen Bibliothek (das heißt: Namen von globalen Variablenlisten, Funktionsbausteinen etc.)
7. Baustein- oder Typnamen aus einer angezogenen Bibliothek
8. Namensräume von lokal angezogenen Bibliotheken und Bibliotheken, die von lokal angezogenen Bibliotheken veröffentlicht werden
Uneindeutige Zugriffe und qualifizierte Zugriffe
Trotz dieser Suchreihenfolgen kann es zu uneindeutigen Zugriffen kommen. Das ist zum
Beispiel der Fall, wenn eine Variable mit dem gleichen Namen in zwei globalen Variablenlisten
vorkommt, die nicht qualifizierten Zugriff erfordern. Einen solchen Fall meldet der
Compiler als Fehler (zum Beispiel: nicht eindeutige Verwendung des Namens XXX
).
Eine solche uneindeutige Verwendung lässt sich durch einen qualifizierten Zugriff,
also beispielsweise durch den Zugriff über den Namen der globalen Variablenliste,
eindeutig machen (zum Beispiel: GVL.XXX
).
Ein qualifizierter Zugriff lässt sich auch immer dazu nutzen, um Verschattungsregeln zu umgehen.
-
Mit dem Namen der globalen Variablenliste kann eindeutig auf eine Variable in dieser Liste zugegriffen werden
-
Mit dem Namen einer Bibliothek kann eindeutig auf Elemente in dieser Bibliothek zugegriffen werden
-
Mit dem Pointer
THIS
kann eindeutig auf Variablen in einem Funktionsbaustein zugegriffen werden, auch wenn eine lokale Variable mit gleichem Namen in einer Methode des Funktionsbausteins existiert
Um jederzeit die Deklarationsstelle eines Bezeichners zu finden, wählen Sie den Befehl „Bearbeiten Symbol suchen Gehe zur Definition“. Dies kann insbesondere dann hilfreich sein, wenn der Compiler eine scheinbar unverständliche Fehlermeldung produziert.
Suchen in Instanzpfaden
Die oben beschriebenen Suchreihenfolgen gelten nicht für Bezeichner, die in einem Instanzpfad als Komponente auftauchen, oder für Bezeichner, die als Eingänge in Aufrufen verwendet werden.
Für einen Zugriff der folgenden Art yy.component
hängt es von der Entität ab, die durch yy
beschrieben wird, wo nach der Deklaration von component
gesucht wird.
Wenn yy
eine Variable mit strukturiertem Datentyp bezeichnet (also vom Typ STRUCT
oder UNION
), dann wird component
in dieser Reihenfolge gesucht:
-
Lokale Variablen des Funktionsbausteins
-
Lokale Variablen des Basis-Funktionsbausteins
-
Methoden des Funktionsbausteins
-
Methoden des Basis-Funktionsbausteins
Wenn yy
eine globale Variablenliste bezeichnet oder ein Programm, dann wird component
nur in dieser Liste gesucht.
Wenn yy
einen Namensraum einer Bibliothek bezeichnet, dann wird component
in dieser Bibliothek genau so gesucht, wie es im obigen Abschnitt "Suchreihenfolge
in der Bibliothek" beschrieben ist.
Erst in zweiter Instanz entscheidet der Compiler, ob der Zugriff auf das gefundene Element erlaubt ist, das heißt, ob die Variable möglicherweise nur lokal zugreifbar ist, oder ob eine Methode privat ist. Wenn der Zugriff nicht erlaubt ist, dann wird ein Fehler ausgegeben.