La parola chiave restrict è un specificatore per puntatori introdotto nello standard C99. Essa informa il compilatore che il puntatore è l'unico modo per accedere a un oggetto di memoria nell'ambito di visibilità del puntatore. Questo aiuta notevolmente l'ottimizzatore a generare codice macchina più efficiente, specialmente quando si lavora con grandi buffer.
Ad esempio:
void vector_add(int * restrict a, int * restrict b, int * restrict c, size_t n) { for (size_t i = 0; i < n; ++i) c[i] = a[i] + b[i]; }
Qui si presuppone che gli array a, b e c non si sovrappongano. La violazione di questo requisito porta a un comportamento indefinito e a errori difficili da individuare.
L'uso di restrict è raccomandato solo quando si è certi che nessun altro puntatore o percorso secondario punta alla stessa memoria.
Può lo stesso valore di memoria essere visibile contemporaneamente attraverso due puntatori restrict?
Risposta:
No, questo porterà a undefined behavior. Non c'è garanzia che il compilatore tenga conto delle modifiche apportate attraverso il secondo puntatore. Esempio di codice gravemente errato:
void f(int * restrict x, int * restrict y) { x[0] = 1; y[0] = 2; } int main() { int v; f(&v, &v); // Violazione della condizione restrict }
Storia
Nel nucleo di calcolo finanziario, le funzioni ottimizzarono gli array con l'aggiunta di restrict, ma non considerarono che gli array potessero sovrapporsi per requisiti della logica di business. Questo portò a un calcolo errato del bilancio in caso di utilizzo scorretto.
Storia
Il metodo di moltiplicazione batch delle matrici accelerò dopo l'applicazione di restrict, ma in una delle iterazioni l'array dei risultati si sovrapponeva con uno degli array di input — la risposta diventava imprevedibile, il bug veniva rivelato solo attraverso test di carico.
Storia
In una delle funzioni di elaborazione delle immagini, due puntatori a pezzi dello stesso buffer furono accidentalmente dichiarati con restrict. Dopo l'aggiornamento del compilatore e del suo ottimizzatore, il risultato del trattamento delle immagini divenne bruscamente distorto — la causa: il compilatore iniziò a riutilizzare attivamente la cache e ignorava le modifiche.