Meskipun benar bahwa perilaku didefinisikan dengan baik - tidak benar bahwa kompiler dapat "mengoptimalkan konst" dalam arti yang Anda maksud.
Artinya, sebuah kompiler tidak diperbolehkan menganggap bahwa hanya karena parameternya adalah const T* ptr
, memori yang ditunjuk oleh ptr
tidak akan diubah melalui pointer lain. Pointer bahkan tidak harus sama. Ini const
adalah kewajiban, bukan jaminan - kewajiban Anda (= fungsi) untuk tidak melakukan perubahan melalui pointer itu.
Untuk benar-benar memiliki jaminan itu, Anda harus menandai penunjuk dengan restrict
kata kunci. Jadi, jika Anda mengkompilasi dua fungsi ini:
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;
}
yang foo()
fungsi harus membaca dua kali dari x
, sementara bar()
hanya perlu membaca sekali:
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
Lihat ini hidup GodBolt.
restrict
hanya kata kunci dalam C (sejak C99); sayangnya, belum diperkenalkan ke C ++ sejauh ini (untuk alasan yang buruk yang lebih rumit untuk memperkenalkannya di C ++). Namun, banyak kompiler yang mendukungnya __restrict
.
Intinya: Kompiler harus mendukung use case "esoterik" Anda saat kompilasi f()
, dan tidak akan memiliki masalah dengannya.
Lihat posting ini tentang kasus penggunaan untuk restrict
.
const
bukan "kewajiban Anda (= fungsi) untuk tidak melakukan perubahan melalui pointer itu". Standar C memungkinkan fungsi untuk menghapusconst
melalui gips dan kemudian memodifikasi objek melalui hasilnya. Pada dasarnya,const
ini hanyalah saran dan kemudahan bagi programmer untuk membantu menghindari memodifikasi objek secara tidak sengaja.