per il compilatore di fare l'ottimizzazione, si deve essere sicuri che a prescindere da come bar
è implementato, e come foo
viene chiamato, il comportamento ben definito non cambierà.
Poiché l'implementazione di bar
e la chiamata a foo
sono sconosciute al compilatore, quando compila foo
, l'esistenza teorica di tale caso è sufficiente per impedire l'ottimizzazione, anche se non si verifica nella realtà.
Ecco un esempio per una situazione del genere. I punti importanti sono: 1. Il parametro p
punta alla memoria di sola scrittura (ad esempio, I/O mappato in memoria).
2. bar
non è sicuro per l'utilizzo con un puntatore di sola scrittura (forse lo scrive e quindi lo legge di nuovo, in attesa dello stesso valore).
La funzione foo
è sicura per l'uso con un puntatore di sola scrittura, poiché scrive solo p
. Questo è vero anche se bar
non è sicuro, perché bar
non ottiene mai p
. Con l'opzione suggerita, bar
ottiene p
, che potrebbe causare problemi.
Ecco un esempio per il file contenente bar
e la chiamata a foo
.
static int increment;
void bar(int *restrict p) {
(*p)=0;
if (increment) (*p)++;
}
void foo(int *restrict p);
int main(int ac, char **av) {
int *p = get_io_addr(); /* Get a write-only memory mapped I/O address */
increment = atoi(av[1]);
foo(p);
return 0;
}
Vedo che questi frammenti potrebbero non essere equivalenti tra loro se non fossero indicatori "limitati". Ma non so perché questi non vengano ottimizzati nel caso "restrict". –
Cosa succede se 'pippo' ottiene un puntatore alla memoria di sola scrittura (ad esempio, I/O mappato in memoria)? Senza l'ottimizzazione è OK, ma no con esso - 'bar' può scrivere-leggere-scrivere. – ugoren
@ugoren: per tali puntatori, è assolutamente necessario utilizzare il qualificatore 'volatile'. Altrimenti, al compilatore è permesso di ottimizzarlo comunque (in alcuni casi, come conoscere il corpo di 'bar'). – jpalecek