Espressioni come Istruzioni in Linguaggio C

In linguaggio C esiste una stretta relazione tra espressioni e istruzioni.

In particolare, in C è possibile usare un'espressione laddove è richiesta un'istruzione. In questa lezione approfondiremo questo concetto. Inoltre approfondiremo il concetto di effetti collaterali e il comportamento dei compilatori in presenza di espressioni come istruzioni.

Espressioni come istruzioni

Il linguaggio C, e tutti i linguaggi da esso derivati come il C++, permettono di utilizzare espressioni come istruzioni.

In altre parole, un'espressione qualsiasi, indipendentemente dalla sua complessità o dal tipo di dato che restituisce, può essere utilizzata come istruzione inserendo un punto e virgola alla fine.

Ad esempio, la seguente riga di codice è un'espressione che restituisce il valore 5, e può essere utilizzata come istruzione:

2 + 3;

Quello che accade quando viene eseguita questa istruzione è che il risultato dell'espressione viene calcolato, ma non viene memorizzato in nessuna variabile e non viene utilizzato in alcun modo. Il risultato viene scartato.

Ovviamente, un'espressione il cui risultato viene scartato non ha molto senso, a meno che non abbia effetti collaterali.

Ad esempio, prendiamo l'istruzione che segue:

x++;

Questa istruzione incrementa il valore della variabile x di 1 e restituisce il valore incrementato. Anche se il risultato dell'espressione viene scartato, l'effetto collaterale è che il valore di x viene incrementato di 1. Quindi la variabile x viene effettivamente modificata.

Prendiamo un altro esempio:

x = 5;

In tal caso si tratta di un'espressione di assegnamento. Per cui, quello che accade è che il valore 5 viene assegnato alla variabile x, e il risultato dell'espressione è il valore assegnato, cioè 5. Anche in questo caso, il risultato dell'espressione viene scartato, ma l'effetto collaterale è che il valore di x viene modificato.

Prendiamo un ultimo esempio:

x * 2 + y;

In tal caso non ci sono effetti collaterali. L'espressione non modifica alcun valore, e il risultato viene scartato. Quindi, in questo caso, l'istruzione non ha alcuno scopo.

Definizione

Espressioni come istruzioni

In linguaggio C qualunque espressione può essere utilizzata come un'istruzione.

La sintassi è la seguente:

espressione;

Quando un'espressione viene utilizzata come istruzione, il risultato dell'espressione viene calcolato, ma viene scartato.

L'istruzione può avere effetti collaterali, come la modifica di variabili. In caso contrario la sua esecuzione non ha alcun effetto.

Effetti collaterali e Compilatori

Inserire un'espressione come istruzione in un programma C può essere utile per sfruttare gli effetti collaterali che essa produce.

Nel caso in cui, però, essa non abbia alcun effetto collaterale, la sua introduzione nel codice può essere considerata un errore di programmazione. Infatti, sebbene essa generi del codice macchina che viene effettivamente eseguito, il risultato dell'espressione viene scartato quindi la presenza dell'istruzione complica inutilmente il codice.

Per questo motivo molti compilatori, tra cui gcc, emettono un avviso o warning quando viene inserita un'espressione come istruzione.

Ad esempio, compilando i nostri programmi con gcc e l'opzione -Wunused-value:

gcc -Wunused-value -o programma programma.c

verrà emesso un avviso per ogni espressione che viene utilizzata come istruzione e che non ha effetti collaterali.

programma.c: In function 'main':
programma.c:5:2: warning: statement with no effect [-Wunused-value]
  5 | 2 + 3;
    | ^~~~~~

Addirittura, se attiviamo le ottimizzazioni con l'opzione -O2, il compilatore potrebbe rimuovere completamente l'istruzione dal codice macchina generato, in quanto non ha alcun effetto. Questo tipo di ottimizzazione prende il nome di Dead Code Elimination (eliminazione del codice morto) o DCE per brevità.

Attraverso la DCE il compilatore è in grado di rilevare e rimuovere dal codice macchina tutte le istruzioni che non hanno alcun effetto, migliorando le prestazioni del programma.

Attenzione, però. Non sempre, come vedremo più in là nelle prossime lezioni, ha senso eliminare del codice che non ha effetti collaterali. Può sembrare contro-intuitivo, ma esistono casi particolari in cui l'eliminazione di codice che non ha effetti collaterali può portare a risultati inaspettati.

In Sintesi

In questa lezione abbiamo visto che in linguaggio C è possibile utilizzare espressioni come istruzioni. Questo significa che qualunque espressione, indipendentemente dalla sua complessità o dal tipo di dato che restituisce, può essere utilizzata come istruzione inserendo un punto e virgola alla fine.

Abbiamo visto che un'espressione utilizzata come istruzione può avere effetti collaterali, come la modifica di variabili. In caso contrario, l'istruzione non ha alcun effetto.

Infine, abbiamo visto che l'utilizzo di espressioni come istruzioni può portare a complicare inutilmente il codice, e che molti compilatori emettono un avviso quando viene inserita un'espressione come istruzione che non ha effetti collaterali.