Skip to main content

Verschattungsregeln

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.

Beispiel 306. Beispiel

Negativbeispiel: Im folgenden Codeausschnitt hat eine lokale Funktionsbaustein-Instanz den gleichen Namen wie eine Funktion:

In einem solchen Fall ist unklar, ob im Programm die Instanz oder die Funktion aufgerufen wird.

FUNCTION YYY : INT
;
END_FUNCTION

FUNCTION_BLOCK XXX
;
END_FUNCTION_BLOCK

PROGRAM PLC_PRG
VAR
    YYY : XXX;
END_VAR
YYY();
END_PROGRAM


Compilerverhalten bei 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.

Verschattung vermeiden

Um sicherzustellen, dass Namen immer eindeutig sind, sollten Namenskonventionen beachtet werden, beispielsweise bestimmte Präfixe für Variablen.

Für weitere Informationen siehe: Bezeichnervergabe

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.

Beispiel: svar_pou := __POOL.POU();

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

    1. Lokale Variablen einer Methode

    2. Lokale Variablen im Funktionsbaustein, Programm oder Funktion und in eventuellen Basisfunktionsbausteinen

    3. Lokale Methoden des Bausteins

  2. Globale Variablen

    1. Globale Variablen in der Applikation, wenn in der Variablenliste, in der die globalen Variablen deklariert sind, nicht das Attribut qualified_only gesetzt ist

    2. Globale Variablen in einer Vaterapplikation, sofern in der Variablenliste, in der die globalen Variablen deklariert sind, nicht das Attribut qualified_only gesetzt ist

    3. Globale Variablen in angezogenen Bibliotheken, wenn weder die Bibliothek noch die Variablenliste qualifizierten Zugriff erfordert

  3. Baustein- oder Typnamen

    1. Baustein- oder Typnamen aus der Applikation (das heißt: Namen von Globalen Variablenlisten, Funktionsbausteinen, etc.)

    2. Baustein- oder Typnamen aus einer Vaterapplikation

    3. Baustein- oder Typnamen aus einer Bibliothek

  4. Bibliotheken

    1. Namensräume von lokal angezogenen Bibliotheken und Bibliotheken, die von Bibliotheken veröffentlicht werden

  5. Ansicht POUs

    1. Globale Variablen in der Ansicht POUs, sofern in der Variablenliste, in der sie deklariert sind, nicht das Attribut qualified_only gesetzt ist

    2. Baustein- oder Typnamen aus der Ansicht POUs (das heißt: Namen von Globalen Variablenlisten, Funktionsbausteinen, etc.)

    3. Bibliotheken aus POUs

Tipp

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

    1. Lokale Variablen einer Methode

    2. Lokale Variablen im Funktionsbaustein, Programm oder Funktion und in eventuellen Basis-Funktionsbausteinen

    3. Lokale Methoden des Bausteins

  2. Globale Variablen

    1. Globale Variablen in der lokalen Bibliothek, wenn die Variablenliste, in der die globalen Variablen deklariert sind, nicht das Attribut qualified_only gesetzt hat

    2. Globale Variablen in angezogenen Bibliotheken, wenn weder die Bibliothek noch die Variablenliste qualifizierten Zugriff erfordert

  3. Bibliotheken

    1. Baustein- oder Typnamen aus der lokalen Bibliothek (das heißt: Namen von globalen Variablenlisten, Funktionsbausteinen, etc.)

    2. Baustein- oder Typnamen aus einer angezogenen Bibliothek

    3. 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.