Es stimmt zwar, dass das Verhalten genau definiert ist, aber es stimmt nicht , dass Compiler in dem von Ihnen gemeinten Sinne "für const optimieren" können.
Das heißt, ein Compiler darf nicht davon ausgehen, dass nur weil ein Parameter a ist const T* ptr, der Speicher, auf den von ptrzeigt, nicht durch einen anderen Zeiger geändert wird. Die Zeiger müssen nicht einmal gleich sein. Dies constist eine Verpflichtung, keine Garantie - eine Verpflichtung von Ihnen (= die Funktion), keine Änderungen über diesen Zeiger vorzunehmen.
Um diese Garantie tatsächlich zu haben, müssen Sie den Zeiger mit dem restrictSchlüsselwort markieren . Wenn Sie also diese beiden Funktionen kompilieren:
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;
}
Die foo()Funktion muss zweimal lesen x, während sie bar()nur einmal lesen muss:
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
Sehen Sie dies live weiter GodBolt.
restrictist nur ein Schlüsselwort in C (seit C99); Leider wurde es bisher nicht in C ++ eingeführt (aus dem schlechten Grund, dass die Einführung in C ++ komplizierter ist). Viele Compiler unterstützen es jedoch irgendwie als __restrict.
Fazit: Der Compiler muss Ihren "esoterischen" Anwendungsfall beim Kompilieren f()unterstützen und hat keine Probleme damit.
Siehe diesen Beitrag zu Anwendungsfällen für restrict.
constist nicht „eine Verpflichtung von Ihnen (= der Funktion), keine Änderungen über diesen Zeiger vorzunehmen“. Der C-Standard ermöglicht es der Funktion,constüber einen Cast zu entfernen und das Objekt dann durch das Ergebnis zu modifizieren. Diesconstist im Wesentlichen nur eine Empfehlung und eine Annehmlichkeit für den Programmierer, um zu vermeiden, dass ein Objekt versehentlich geändert wird.