不断传播
随着 CODESYS Static Analysis 版本V5.0.0.0,代码的分析基于常量传播。恒定传播的结果用于各种检查。例如,它检查指针是否不等于 0,或者数组索引是否超出有效范围。
只需了解静态分析的工作原理及其局限性,您就可以有效地支持静态分析。
不断传播
静态分析尝试根据变量的用途来确定变量的值。
PROGRAM PLC_PRG //Declaration VAR x: INT; bTest: BOOL; END_VAR
//Implementation x := 99; IF x < 100 THEN bTest := TRUE; END_IF
在第 1 行的实现中,常量传播记录了值 99
对于变量 x
使用该值进行进一步分析。然后分析发现以下表达式 IF
- 语句常量 TRUE
是。
局部执行恒定传播
仅在功能块中本地确定值。输入的传递方式无关紧要。函数调用的结果也是无关紧要的。
FUNCTION Func : BOOL //Declaration VAR_INPUT bText : BOOL; END_VAR
//Implementation IF bTest THEN Func := OtherFunc(TRUE); END_IF
即使参数 bTest
被设定为 TRUE
在每次调用时,这对恒定传播没有影响。即使 OtherFunc(TRUE)
总是返回 TRUE
,这对恒定传播没有影响。
只有临时变量才有初始值。
程序和功能块中的静态局部变量没有假定的初始值。这些变量保留上次调用时的值,因此原则上可以是“任何值”。
函数中的局部变量和临时变量在每次调用时都有一个初始值。常数传播用这个初始值进行计算。
PROGRAM PLC_PRG //Declaration VAR x: INT := 6; bTest: BOOL; END_VAR VAR_TEMP y : INT := 8; END_VAR
bText := x < y;
变量 y
每次都会被执行 PLC_PRG
值为 8。变量 x
但也不一定。因此,恒定传播仅用于 y
假设一个值,但不是为了 x
。
建议声明始终先写入然后读取的变量作为临时变量。
常数传播确定数值数据类型的值范围。
为了降低复杂性,为每个变量确定了具有上限和下限的值范围。
PROGRAM PLC_PRG VAR x: INT := 6; bTest: BOOL; y : INT; END_VAR
//Implementation IF bTest THEN x := 1; ELSSE x := 100; END_IF IF x = 77 THEN y := 13; END_IF
这里取值范围 [1..100]
是为变量确定的 x
。结果,在第 7 行,比较 x = 77
不被识别为常量表达式,因为 77
是在数值范围之内。
重复出现的复杂表达式不会被识别为同一变量。
复杂表达式可能没有分配值。如果这样的表达式多次出现,那么引入辅助变量会很有帮助。
PROGRAM PLC_PRG VAR x: DINT; py : POINTER TO INT; y : INT; testArray : ARRAY [0..4] OF DINT; END_VAR
//Implementation IF py^ >= 0 AND py^<= 4 THEN x := testArray[py^]; END_IF y := py^; IF y <= 0 AND y <=4 THEN x := testArray[y]; END_IF
在第 2 行,尽管检查了指针指向的区域,但由于可能通过指针访问某个值,因此会发出错误。如果首先将该值复制到局部变量中并检查其范围,则常量传播可以确定该变量的值范围,并允许访问第 7 行的数组。
分枝
对于分支,单独计算各个分支。然后将各个范围中的值范围组合起来形成新的值范围。
//Implementation IF func(TRUE) THEN x := 1; ELSE x := 10; END_IF IF func(FALSE) THEN y := x; ELSE Y := 2*x; END_IF
6号线, x
有范围 [1..10]
。第 11 行之后, y
有取值范围 [1..20]
;这是两个值范围并集的结果 [1..10]
和 [2..20]
。
状况
条件可以限制代码块中变量的值范围。可以组合多个条件。互斥条件也可能导致空值范围。
IF y > 0 AND y < 10 THEN x := y; ELSE x:= 0; END_IF IF x < 0 THEN i := 99; END_IF
y 的取值范围 [1..9]
第 2 行。这会得出值范围 [0..9]
为了 x
第6行。结合条件 x < 0
,这会导致一组空的可能值 x
第 8 行。该代码无法访问。静态分析将报告该情况 x < 0
总是返回 FALSE
在此刻。
循环播放
常量传播将循环代码,直到循环中变量的值不再改变。假设循环可以运行任意次。到目前为止确定的值与之前的值相结合。在循环内改变的变量具有连续增长的范围。这里,常数传播并不采用所有可能的范围值,而是仅使用代码中出现的限制以及值 0、1、2、3 和 10,因为这些通常是相关的。
描述该过程的最简单方法是通过示例:
PROGRAM PLC_PRG VAR x: DINT; i : DINT; y : DINT; END_VAR
//Implementation x := 0; y := 0; FOR i := 0 TO 5 DO x := x + 1; y := i; END_FOR
常量传播了解有关循环的以下信息:
i
, x
, 和 y
在第一次执行循环开始时为 0。条件 i <= 5
适用于循环中的代码。条件 i > 5
适用于循环后的代码。
对于循环中变量的值,常数传播确定以下值:
|
|
| ||
---|---|---|---|---|
|
|
|
具体来说,经过以下中间步骤:
经过 |
|
|
| |
---|---|---|---|---|
1 | 0 |
|
|
|
2 |
|
|
| |
6 |
|
|
| 一、范围 |
7 |
|
|
| |
10 |
|
|
|
|
11 |
|
|
|
|
截至11日 | 从第11遍开始,循环中的值不会改变。传播结束。 |
此外, i = 6
适用于该循环之后的代码。范围 [0..6]
在循环中确定,并与条件结合 i > 5
,结果恰好是值 6。