Skip to main content

Propagazione costante

Con il CODESYS Static Analysis versione V5.0.0.0, l'analisi del codice si basa sulla propagazione costante. I risultati della propagazione costante vengono utilizzati per vari controlli. Ad esempio, controlla se i puntatori non sono uguali a 0 o se gli indici dell'array non rientrano nell'intervallo valido.

Puoi supportare efficacemente l'analisi statica semplicemente conoscendo come funziona questa analisi e quali sono i suoi limiti.

Propagazione costante

L'analisi statica tenta di determinare il valore di una variabile in base al suo utilizzo.

Esempio 1. Esempio
PROGRAM PLC_PRG
//Declaration
VAR
    x: INT;
    bTest: BOOL;
END_VAR
//Implementation
x := 99;
IF x < 100 THEN
    bTest := TRUE;
END_IF

Nell'implementazione della riga 1 la propagazione costante registra il valore 99 per la variabile x utilizzare questo valore per ulteriori analisi. L'analisi riconosce quindi l'espressione seguente IF-Costante di istruzione TRUE È.



Propagazione costante eseguita localmente

Un valore viene determinato solo localmente nel blocco funzione. È irrilevante il modo in cui viene passato un input. Anche i risultati delle chiamate di funzione sono irrilevanti.

Esempio 2. Esempio
FUNCTION Func : BOOL
//Declaration
VAR_INPUT
    bText : BOOL;
END_VAR
//Implementation
IF bTest THEN
    Func := OtherFunc(TRUE);
END_IF


Anche se il parametro bTest è impostato per TRUE ad ogni chiamata ciò non ha alcun effetto sulla propagazione costante. Anche se OtherFunc(TRUE) ritorna sempre TRUE, questo non ha alcun effetto sulla propagazione costante.

Solo le variabili temporanee hanno valori iniziali.

Le variabili locali statiche nei programmi e nei blocchi funzione non hanno alcun valore iniziale presunto. Le variabili mantengono i valori dell'ultima chiamata e quindi in linea di principio possono essere "qualsiasi cosa".

Le variabili locali nelle funzioni e le variabili temporanee hanno un valore iniziale ad ogni chiamata. La propagazione costante viene calcolata con questo valore iniziale.

Esempio 3. Esempio
PROGRAM PLC_PRG
//Declaration
VAR
    x: INT := 6;
    bTest: BOOL;
END_VAR
VAR_TEMP
    y : INT := 8;
END_VAR
bText := x < y;

La variabile y viene eseguito ogni volta PLC_PRG hanno il valore 8. La variabile x, tuttavia, non necessariamente. Pertanto, la propagazione costante viene utilizzata solo per y assumere un valore, ma non per x.

Si consiglia di dichiarare variabili che vengono sempre scritte prima e poi lette come variabili temporanee.



La propagazione costante determina gli intervalli di valori per i tipi di dati numerici.

Per ridurre la complessità, per ciascuna variabile viene determinato un intervallo di valori con limiti superiore e inferiore.

Esempio 4. Esempio
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

Ecco l'intervallo di valori [1..100] è determinato per la variabile x. Di conseguenza, alla riga 7, il confronto x = 77 non è riconosciuto come espressione costante perché 77 rientra nell'intervallo di valori.



Le espressioni complesse ricorrenti non vengono riconosciute come la stessa variabile.

Alle espressioni complesse potrebbe non essere assegnato un valore. Se tali espressioni ricorrono più volte, è utile introdurre una variabile ausiliaria.

Esempio 5. Esempio
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

Alla riga 2 viene emesso un errore per un possibile accesso tramite puntatore ad un valore, sebbene venga controllata l'area puntata dal puntatore. Se il valore viene prima copiato in una variabile locale e il suo intervallo viene controllato, la propagazione costante può determinare l'intervallo di valori per quella variabile e consentire l'accesso all'array alla riga 7.



Ramificazione

Per quanto riguarda la ramificazione, i singoli rami vengono calcolati separatamente. Gli intervalli di valori dei singoli intervalli vengono quindi combinati per formare un nuovo intervallo di valori.

Esempio 6. Esempio
//Implementation
IF func(TRUE) THEN
    x := 1;
ELSE 
    x := 10;
END_IF

IF func(FALSE) THEN
    y := x;
ELSE
    Y := 2*x;
END_IF

Sulla linea 6, x ha la portata [1..10]. Dopo la linea 11, y ha l'intervallo di valori [1..20]; questo risulta dall'unione dei due intervalli di valori [1..10] E [2..20].



Condizioni

Esempio 7. Esempio

Le condizioni possono limitare l'intervallo di valori di una variabile in un blocco di codice. È possibile combinare diverse condizioni. Condizioni che si escludono a vicenda possono anche risultare in un intervallo di valori vuoto.

IF y > 0 AND y < 10 THEN
    x := y;
ELSE
    x:= 0;
END_IF
IF x < 0 THEN
    i := 99;
END_IF

y ha l'intervallo di valori [1..9] sulla riga 2. Ciò risulta nell'intervallo di valori [0..9] per x alla riga 6. Combinato con la condizione x < 0, il risultato è un insieme vuoto di possibili valori per x alla riga 8. Il codice non è accessibile. L'analisi statica riporterà la condizione x < 0 ritorna sempre FALSE a questo punto.



Ciclo

La propagazione costante eseguirà il loop del codice finché i valori delle variabili nel loop non cambieranno più. Si presuppone che un ciclo possa essere eseguito un numero qualsiasi di volte. I valori finora determinati vengono combinati con i valori precedenti. Le variabili che vengono modificate all'interno del ciclo hanno un intervallo crescente. In questo caso la propagazione costante non accetta tutti i valori possibili per gli intervalli, ma utilizza solo i limiti presenti nel codice e anche i valori 0, 1, 2, 3 e 10 perché questi sono spesso rilevanti.

Esempio 8. Esempio

Il modo più semplice per descrivere la procedura è tramite un esempio:

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

La propagazione costante conosce quanto segue riguardo al ciclo:

i, x, E y sono 0 all'inizio della prima esecuzione del ciclo. La condizione i <= 5 si applica al codice nel loop. La condizione i > 5 si applica al codice dopo il ciclo.

Per i valori delle variabili nel ciclo, la propagazione costante determina i seguenti valori:

i

x

y

[0..5]

[0..MAXDINT]

[0..5]

Nel dettaglio si attraversano i seguenti passaggi intermedi:

Passaggio

i

x

y

1

0

[0..1]

0

i è stato inizializzato con 0; y ottiene sempre gli stessi valori di i.

2

[0..1]

[0..2]

[0..1]

6

[0..5]

[0..6]

[0..5]

Innanzitutto, la gamma [0..6] è effettivamente calcolato i. Questo però è noto i < 5 è una condizione. Pertanto, il valore del codice nel ciclo è limitato a questo valore.

7

[0..5]

[0..7]

[0..5]

10

[0..5]

[0..10]

[0..5]

x viene incrementato sempre di più. Da 10, tuttavia, il valore viene "arrotondato per eccesso" a MAXINT.

11

[0..5]

[0..MAXDINT]

[0..5]

MAXDINT + 1 risultati in MAXDINT

A partire dalle 11

Dall'undicesimo passaggio i valori nel ciclo non cambieranno. La propagazione è terminata.

Inoltre, i = 6 si applica al codice che segue questo ciclo. La gamma [0..6] viene determinato nel ciclo e questo viene combinato con la condizione i > 5, che risulta esattamente nel valore 6.