Se è vero che il comportamento è ben definito - è non è vero che i compilatori possono "Ottimizza per const", nel senso che vuoi dire.
Cioè, un compilatore non è ammesso che solo perché un parametro è a const T* ptr, la memoria indicata da ptrnon verrà modificata tramite un altro puntatore. I puntatori non devono nemmeno essere uguali. Il constè un obbligo, non una garanzia - un obbligo da voi (= la funzione) di non apportare modifiche attraverso tale puntatore.
Per avere effettivamente quella garanzia, è necessario contrassegnare il puntatore con la restrictparola chiave. Pertanto, se si compilano queste due funzioni:
int foo(const int* x, int* y) {
int result = *x;
(*y)++;
return result + *x;
}
int bar(const int* x, int* restrict y) {
int result = *x;
(*y)++;
return result + *x;
}
la foo()funzione deve leggere due volte da x, mentre bar()deve leggerlo solo una volta:
foo:
mov eax, DWORD PTR [rdi]
add DWORD PTR [rsi], 1
add eax, DWORD PTR [rdi] # second read
ret
bar:
mov eax, DWORD PTR [rdi]
add DWORD PTR [rsi], 1
add eax, eax # no second read
ret
Guarda questo dal vivo GodBolt.
restrictè solo una parola chiave in C (dal C99); sfortunatamente, finora non è stato introdotto in C ++ (per la scarsa ragione che è più complicato introdurlo in C ++). Molti compilatori lo supportano, comunque, come __restrict.
In conclusione: il compilatore deve supportare il caso d'uso "esoterico" durante la compilazione f()e non avrà alcun problema con esso.
Vedi questo post relativo ai casi d'uso per restrict.
constnon è "un obbligo da parte tua (= la funzione) di non apportare modifiche tramite quel puntatore". Lo standard C consente di rimuovere la funzioneconsttramite un cast e quindi modificare l'oggetto attraverso il risultato. In sostanza,constè solo una consulenza e una comodità per il programmatore per aiutare a evitare di modificare inavvertitamente un oggetto.