Bedingte Pragmas

Überblick

Die Programmiersprache ExST (Extended ST) unterstützt mehrere bedingte Pragma-Anweisungen, die die Code-Generierung im Prä-Kompilierungs- oder Kompilierungsprozess beeinflussen.

HINWEIS: Verwenden Sie keine bedingten Pragmas im Deklarationsteil. Sie werden nicht beachtet.

Ob ein Implementierungs-Code bei der Kompilierung berücksichtigt wird, kann von den nachstehenden Bedingungen abhängig sein, nämlich ob:

  • ein bestimmter Datentyp oder eine bestimmte Variable deklariert ist

  • ein Datentyp oder eine Variable ein bestimmtes Attribut hat

  • eine Variable einen bestimmten Datentyp hat

  • eine bestimmte POU oder eine Task vorhanden bzw. Teil des Aufrufbaums ist usw.

HINWEIS: Es ist nicht möglich, für eine POU oder GVL, die im POU-Baum deklariert ist, eine {define...} zu verwenden, die in einer Applikation deklariert ist. Definitionen in Applikationen wirken sich nur auf Schnittstellen unterhalb der entsprechenden Applikation aus.

{define identifier string}

Während des Prä-Kompilierungsprozesses werden alle nachfolgenden Instanzen des Bezeichners (identifier) mit der angegebenen Zeichenfolge (string) ersetzt, wenn diese nicht leer ist (was erlaubt ist). Die Kennung bleibt definiert und im Umfang bis zum Ende des Objektes oder bis sie in einer {undefine} -Weisung undefiniert wird. Wird für eine bedingte Kompilierung benötigt.

{undefine identifier}

Die Präprozessordefinition der identifier (nach {define}, siehe erste Zeile dieser Tabelle) wird entfernt und die Kennung ist demzufolge undefiniert. Wenn der angegebene Bezeichner gerade gar nicht definiert ist, wird das pragma ignoriert.

{IF expr}

...

{ELSIF expr}

...

{ELSE}

...

{END_IF}

Dies sind pragmas für die bedingte Kompilierung. Die angegebenen Ausdrücke exprs müssen zur Kompilierungszeit konstant sein; sie werden in der Reihenfolge ausgewertet, in der sie hier erscheinen, bis einer der Ausdrücke einen nicht-Null-Wert zeigt. Der mit der Anweisung verknüpfte Text wird vorverarbeitet und dann übersetzt; die anderen Zeilen werden ignoriert. Die Reihenfolge der Abschnitte ist festgelegt; jedoch sind die Abschnitte elsif und else optional, und die elsif-Abschnitte dürfen beliebig oft vorkommen.

Innerhalb der Konstante expr können mehrere bedingte Kompilierungsoperatoren verwendet werden.

<expr>

Innerhalb des konstanten Ausdrucks expr einer bedingten Kompilierung pragma ({if} oder {elsif}) (siehe vorherige Tabelle) können Sie verschiedene Operatoren verwenden. Diese Operatoren dürfen nicht via {undefine} oder {define} undefiniert oder redefiniert werden.

Sie können diese Ausdrücke genau wie die von {define} vervollständigte Definition im Textfeld Compiler definiert: im Dialogfeld Eigenschaften eines Objektes verwenden (Ansicht > Eigenschaften > Generieren).

defined (identifier)

Dieser Operator bewirkt, dass der Ausdruck den Wert TRUE erhält, sobald identifier mit einer {define} -Anweisung definiert und nicht zu einem späteren Zeitpunkt durch eine {undefine} -Anweisung undefiniert wurde. Andernfalls wird der Wert FALSE ausgeliefert.

Beispiel zu defined (identifier):

Voraussetzung: Es gibt 2 Anwendungen App1 und App2. Der Bezeichner pdef1 wird in App2 deklariert, aber nicht in App1.

{IF defined (pdef1)}
    (* this code is processed in App1 *)
    {info 'pdef1 defined'}
    hugo := hugo + SINT#1;
{ELSE}
    (* the following code is only processed in application App2 *)
    {info 'pdef1 not defined'}
    hugo := hugo - SINT#1;
{END_IF}

Außerdem wird ein Beispiel für eine Meldung pragma hinzugefügt:

Nur die Information pdef1 defined wird beim Kompilieren der Applikation in der Ansicht Meldungen angezeigt, weil pdef1 definiert ist. Die Meldung nicht definiert erscheint, wenn pdef1pdef1 nicht definiert ist.

defined (variable:variable)

Bei einer Applikation auf eine Variable, bewirkt dieser Operator, dass der Ausdruck den Wert TRUE erhält, wenn diese Variable im aktuellen Bereich deklariert ist. Andernfalls entspricht der Wert FALSE.

Beispiel zu defined (variable:variable):

Voraussetzung: Es gibt 2 Anwendungen App1 und App2. Variable g_bTest wird in App2 deklariert, aber nicht in App1.

{IF defined (variable:g_bTest)}
(* the following code is only processed in application App2 *)
g bTest := x > 300;
{END_IF}

defined (type:identifier)

Bei einer Applikation auf einen Datentyp Kennung, bewirkt dieser Operator, dass der Ausdruck den Wert TRUE erhält, wenn ein Datentyp mit diesem bestimmten Namen deklariert ist. Andernfalls entspricht der Wert FALSE.

Beispiel zu defined (type:identifier) :

Voraussetzung: Es gibt 2 Anwendungen App1 und App2. Datentyp DUT wird in App2 deklariert, aber nicht in App1.

{IF defined (type:DUT)}
(* the following code is only processed in application App1 *)
bDutDefined := TRUE;
{END_IF}

defined (pou:pou-name)

Bei einer Applikation auf einen POU-Namen, bewirkt dieser Operator, dass der Ausdruck den Wert TRUE erhält, wenn eine POU oder Aktion mit diesem bestimmten POU-Namen definiert ist. Andernfalls entspricht der Wert FALSE.

Beispiel zu defined (pou: pou-name):

Voraussetzung: Es gibt 2 Anwendungen App1 und App2. POU CheckBounds ist in App2 verfügbar, aber nicht in App1.

{IF defined (pou:CheckBounds)}
(* the following code is only processed in application App1 *)
arrTest[CheckBounds(0,i,10)] := arrTest[CheckBounds(0,i,10)] + 1;
{ELSE}
(* the following code is only processed in application App2 *)
arrTest[i] := arrTest[i]+1;
{END_IF} 

hasattribute (pou: pou-name, attribute)

Bei einer Applikation auf einen POU bewirkt dieser Operator, dass der Ausdruck den Wert TRUE erhält, wenn dieses besondere attribute in der ersten Zeile des POU-Deklarationsteils angegeben ist.

Beispiel zu hasattribute (pou: pou-name, attribute):

Voraussetzung: Es gibt 2 Anwendungen App1 und App2. Funktion fun1 ist in App1 und App2 definiert, hat in App1 jedoch ein Attributvision:

Definition von fun1 in App1:

{attribute 'vision'}
FUNCTION fun1 : INT
VAR_INPUT
i : INT;
END_VAR
VAR
END_VAR

Definition von fun1 in App2:

FUNCTION fun1 : INT
VAR_INPUT
i : INT;
END_VAR
VAR
END_VAR

Pragma-Anweisung

{IF hasattribute (pou: fun1, 'vision')}
(* the following code is only processed in application App1 *)
ergvar := fun1 ivar);
{END_IF}

hasattribute (variable: variable, attribute)

Wenn auf ein variable angewendet, ist der Wert TRUE, wenn dieses bestimmte Attribut durch die {attribute}-Anweisung in einer Zeile vor der Deklaration der Variable spezifiziert wird.

Beispiel zu hasattribute (variable: variable, attribute):

Voraussetzung: Es gibt 2 Anwendungen App1 und App2. Variable g_globalInt wird in App1 und App2 verwendet, hat in App1 jedoch ein AttributDoCount:

Deklaration von g_globalInt in App1:

VAR_GLOBAL
{attribute 'DoCount'}
g_globalInt : INT;
g_multiType : STRING;
END_VAR

Deklaration von g_globalInt in App2:

VAR_GLOBAL
g_globalInt : INT;
g_multiType : STRING;
END_VAR

Pragma-Anweisung

{IF hasattribute (variable: g_globalInt, 'DoCount')}
(* the following code line will only be processed in App1, because there variable g_globalInt has got the attribute 'DoCount' *)
g_globalInt := g_globalInt + 1;
{END_IF}

hastype (variable:variable, type-spec)

Bei einer Applikation auf eine variable, ist dieser Wert TRUE, wenn diese Variable das spezifizierte type-spec hat. Andernfalls entspricht der Wert FALSE.

Verfügbare Datentypen von type-spec

  • BOOL

  • BYTE

  • DATE

  • DATE_AND_TIME

  • DINT

  • DWORD

  • INT

  • LDATE

  • LDATE_AND_TIME (LDT)

  • LINT

  • LREAL

  • LTIME

  • LTIME_OF_DAY (LTOD)

  • LWORD

  • REAL

  • SINT

  • STRING

  • TIME

  • TIME_OF_DAY (TOD)

  • UDINT

  • UINT

  • ULINT

  • USINT

  • WORD

  • WSTRING

Beispiel zu Operator hastype (variable: variable, type-spec):

Voraussetzung: Es gibt 2 Anwendungen App1 und App2. Variable g_multitype wird in App1 mit dem Typ LREAL und in der Applikation App2 mit dem Typ STRING deklariert:

{IF (hastype (variable: g_multitype, LREAL))}
(* the following code line will be processed only in App1 *)
g_multitype := (0.9 + g_multitype) * 1.1;
{ELSIF (hastype (variable: g_multitype, STRING))}
(* the following code line will be processed only in App2 *)
g_multitype := 'this is a multitalent';
{END_IF}

hasvalue (define-ident, char-string)

Dieser Operator bewirkt, dass der Ausdruck den Wert TRUE erhält, wenn eine Variable mit dem Bezeichner (define-ident) definiert ist und den Wert (char-string) hat. Andernfalls entspricht der Wert FALSE.

Beispiel zu hasvalue (define-ident, char-string):

Voraussetzung: Die Variable test wird in den Anwendungen App1 und App2 verwendet. Sie erhält in App1 den Wert 1 und in App2 den Wert 2:

{IF hasvalue(test,'1')}
(* the following code line will be processed in App1, because there variable test has value 1 *)
x := x + 1;
{ELSIF hasvalue(test,'2')}
(* the following code line will be processed in App1, because there variable test has value 2 *)
x := x + 2;
{END_IF}

hasconstantvalue(<variable>, <literal expression>)

Verwenden Sie diesen Operator, um den deklarierten Wert einer Konstante anzufordern.

Beispiel:

{IF hasconstantvalue(test,1)}
(*  the following code is only processed in App1 *)
    x := x + 1;
{ELSIF hasconstantvalue(test,2)}
(*  the following code is only processed in App2 *)
    x := x + 2;
{END_IF}

NOT operator

Dieser Ausdruck erhält den Wert TRUE, wenn der Umkehrwert von operator den Wert TRUE liefert. operator kann jeweils einer der in der vorliegenden Tabelle beschriebenen Operatoren sein.

Beispiel zu NOT operator:

Voraussetzung: Es gibt 2 Anwendungen App1 und App2. POU PLC_PRG1 wird in App1 und App2 verwendet. POU CheckBounds ist nur in App1 verfügbar:

{IF defined (pou: PLC_PRG1) AND NOT (defined (pou: CheckBounds))}
(* the following code line is only executed in App2 *)
bANDNotTest := TRUE;
{END_IF}

AND operator

Der Ausdruck erhält den Wert TRUE, wenn beide Operationen den Wert TRUE haben. operator kann einer der in dieser Tabelle beschriebenen Operatoren sein.

Beispiel zu AND operator:

Voraussetzung: Es gibt 2 Anwendungen App1 und App2. POU PLC_PRG1 wird in den Applikationen App1 und App2 verwendet. POU CheckBounds ist nur in App1 verfügbar:

{IF defined (pou: PLC_PRG1) AND (defined (pou: CheckBounds))}
(* the following code line will be processed only in applications App1, because only there "PLC_PRG1" and "CheckBounds" are defined *)
bORTest := TRUE;
{END_IF}

OR operator

Der Ausdruck erhält den Wert TRUE, wenn einer der Operatoren TRUE liefert. operator kann jeweils einer der in der vorliegenden Tabelle beschriebenen Operatoren sein.

Beispiel zu OR operator:

Voraussetzung: POU PLC_PRG1 wird in den Applikationen App1 und App2 verwendet. POU CheckBounds ist nur in App1 verfügbar:

{IF defined (pou: PLC_PRG1) OR (defined (pou: CheckBounds))}
(* the following code line will be processed in applications App1 and App2, because both contain at least one of the POUs "PLC_PRG1" and "CheckBounds" *)
bORTest := TRUE;
{END_IF}

(operator)

(operator) umklammert den Operator.