Un punto di sequenza (sequence point) è un punto nell'esecuzione di un programma informatico nel quale è garantito il fatto che tutti gli effetti collaterali delle istruzioni precedenti siano stati realizzati e nessun effetto collaterale delle istruzioni seguenti sia stato realizzato. I punti di sequenza sono un concetto chiave in linguaggi come C e C++, nei quali sono importanti per determinare la validità di una certa istruzione. L'aggiunta di ulteriori punti di sequenza nel codice può essere necessaria, ad esempio, per rendere un'espressione ben definita e garantire l'unicità dell'ordine di valutazione delle operazioni in essa contenute.
In C++11 l'espressione sequence point è stata sostituita da sequencing. Date due espressioni, vi sono tre possibili casi di sequencing:
Mentre nel primo caso la semantica del programma è ben definita, gli altri due casi sono problematici. In particolare, la valutazione di espressioni unsequenced può sovrapporsi e, se le due espressioni dipendono da uno stato condiviso, il risultato è indefinito e può avere effetti catastrofici. Tale situazione è un problema che si può incontrare facilmente in calcolo parallelo (corsa critica), ma può verificarsi anche in programmi strettamente sequenziali. Ad esempio, nella valutazione dell'espressione (a = 1) + (b = a) parte dell'assegnamento a = 1 (es. metà dei bit) può essere completato prima di b = a e parte dopo, per cui al termine della valutazione b può contenere uno stato intermedio di a, totalmente privo di significato.
Date due funzioni f() e g(), poiché in C e C++ l'operatore + non genera un punto di sequenza, nella valutazione di f()+g() non è possibile sapere a priori quale chiamata tra f() e g() verrà valutata per prima. Al contrario, l'operatore virgola introduce un punto di sequenza, per cui nella valutazione dell'espressione f(),g() la chiamata f() verrà sempre valutata (e i suoi effetti collaterali realizzati) prima della valutazione di g().
I punti di sequenza svolgono un ruolo importante nel definire il comportamento di espressioni che manipolano più volte una stessa variabile. Un esempio comune in C è l'espressione i=i++, che apparentemente assegna ad i il suo stesso valore ed incrementa la variabile i. In realtà il valore finale di i al termine della valutazione non è definito, poiché l'operatore di assegnamento non determina un punto di sequenza, per cui l'incremento potrebbe essere eseguito prima, durante, o dopo l'assegnamento. Altri linguaggi possono avere regole diverse: per esempio il C# definisce la precedenza degli operatori di assegnamento e di incremento in modo tale da garantire che il risultato dell'espressione i=i++ sia corretto e ben definito.
In C e C++, punti di sequenza sono garantiti nei seguenti casi:
&&, || (come conseguenza della valutazione a corto circuito), e operatore virgola. Ad esempio, nella valutazione dell'espressione *p++ != 0 && *q++ != 0 tutti gli effetti collaterali dell'espressione *p++ != 0 sono completati prima di ogni tentativo di accedere alla variabile q.?: e i due rimanenti operandi. Ad esempio, nella valutazione dell'espressione a = (*p++) ? (*p++) : 0 c'è un punto di sequenza dopo il primo *p++ il che significa che l'incremento prescritto nel primo operando è stato già eseguito quando il secondo accesso a p dovesse avvenire.a=b;), l'istruzione return, i costrutti di controllo dell'esecuzione tramite la valutazione di una condizione if, switch, while, e do-while, e tutte e tre le espressioni nel blocco di controllo di un ciclo for.f(i++) + g(j++) + h(k++), la funzione f è chiamata con un argomento il cui valore è uguale a i prima dell'incremento, ma la variabile i è stata già aumentata quando l'esecuzione del corpo di f ha inizio. Analogamente, j e k sono incrementate prima di valutare il corpo delle rispettive funzioni g e h. Tuttavia l'ordine in cui f(), g() e h() sono eseguite non è definito, né è definito l'ordine in cui sono eseguiti gli incrementi delle tre variabili i, j, k. Se il corpo di f dovesse accedere alle variabili j and k, potrebbe verificarsi che nessuna, solo una, o entrambe le variabili siano state già incrementate. È importante notare che le virgole che compaiono nella chiamata f(a,b,c) non sono istanze dell'operatore virgola, ma sono token che formano la sintassi della chiamata di funzione, e non introducono punti di sequenza, per cui l'ordine di valutazione degli argomenti non è definito.5 nella dichiarazione int a = 5;.a++ nell'istruzione code>int x = a++, y = a++. È importante sottolineare che, anche in questo caso, la virgola è parte della sintassi della dichiarazione, non è un operatore virgola.printf("foo %n %d", &a, 42) è presente un punto di sequenza dopo la valutazione di %n e prima della stampa di 42.In C++, gli operatori soggetti ad overloading si comportano come normali funzioni per quanto riguarda l'introduzione di punti di sequenza.