You should use AND_THEN. OR_ELSE?

In this post I’ll discuss the operators ‘AND_THEN‘ and ‘OR_ELSE‘. Operators which I find really useful from time to time.

What is it?

In structured text all operators of an expression are checked, regardless of previous evaluation results in the same expression.

For example:

IF 1 › 2 AND Evaluate() THEN
    ThisWillNeverBeCalled();
END_IF

Even tough we immediately notice the this expression will never reach true due to the expression ‘1 › 2’, the method Evaluate() will be called.

This principle also goes for the following statement:

IF 2 › 1 OR Evaluate() THEN
    ThisWillAlwaysBeCalled();
END_IF

This expression will always return true due to the expression ‘2 › 1’. However, the method Evaluate() will still be called.

To prevent this we have the operators ‘AND_THEN‘ and ‘OR_ELSE’ available.
If we use the AND_THEN operator in the first example:

IF 1 › 2 AND_THEN Evaluate() THEN
    ThisWillNeverBeCalled();
END_IF

The method Evaluate() will not be called.
Likewise with the second example:

IF 2 › 1 OR_ELSE Evaluate() THEN
    ThisWillAlwaysBeCalled();
END_IF

The method Evaluate() will not be called.

When to use it

Ok now we know how they work, when do you need it? Well I’ve some use cases.

Consider a classic pointer null check:

IF ptrFunctionBlock ‹› 0 THEN
    IF ptrFunctionBlock^().Evaluate() THEN
        Execute();
    END_IF
END_IF

This cannot be simplified to:

//Bad example.
IF ptrFunctionBlock ‹› 0 AND ptrFunctionBlock^().Evaluate() THEN
    Execute();
END_IF

Because we just learned that regardless of the first expression, ptrFunctionBlock^().Evaluate() will be called. With a possible null reference exception as result.
But with the AND_THEN operator this example will work!

IF ptrFunctionBlock ‹› 0 AND_THEN ptrFunctionBlock^().Evaluate() THEN
    Execute();
END_IF

Another trick I often use is the usage input buttons with light feedback. Each button is a function block which will automatically blink the button LED when my program checks the status of the button by calling a property named ‘RisingEdgeBlinkFeedback’. Besides returning the button state it will also activate the LED of the button for 50ms.  If I would not use AND_THEN my button would blink way to often.

An example of this:

IF PreProcessConditionsAreMet AND_THEN StartButton.RisingEdgeBlinkFeedback THEN
    Process.Execute := TRUE;
END_IF

With an AND operator the button LED would blink before activating the button has effect.
Similar is a case where I use the OR_ELSE operator:

IF PreProcessConditionsAreMet AND_THEN AutoStartProcess OR_ELSE StartButton.RisingEdgeBlinkFeedback THEN
    Process.Execute := TRUE;
END_IF

If the variable ‘AutoStartProcess’ is true, I do not want my start button to blink. So I use the OR_ELSE operator the exit the expression before it will check the start button.

Conclusion

In Structured Text all expressions are evaluated regardless of their evaluation. With the operators ‘AND_THEN‘ and ‘OR_ELSE‘ we can alter this behavior and escape an expression evaluation early. The operators do not add new possibilities but they can help you to write cleaner code of which this post showed some examples. More information about these operators can be found here and here.

 

Gerhard Barteling

Gerhard is a mechatronic engineer with a predilection for software engineering.