Davranışın iyi tanımlanmış olduğu doğru olsa da - derleyicilerin demek istediğiniz anlamda "const için optimize edebileceği" doğru değildir .
Olduğunu, bir derleyici olduğu değil izin verilen bir parametre olduğunu sırf varsayalım const T* ptr
tarafından, bellek işaret ptr
başka işaretçi üzerinden değişmeyecektir. İşaretçilerin eşit olması bile gerekmez. Bu const
bir yükümlülük değil, bir garantidir - sizin tarafınızdan (= işlev) bu işaretçi aracılığıyla değişiklik yapmama yükümlülüğüdür.
Bu garantiyi alabilmek için işaretçiyi restrict
anahtar kelimeyle işaretlemeniz gerekir . Bu nedenle, bu iki işlevi derlerseniz:
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;
}
foo()
fonksiyon iki kez gelen okumalı x
ederken, bar()
sadece bir kez okumak gerekir:
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
Bunu canlı olarak izleyin GodBolt.
restrict
yalnızca C dilinde bir anahtar kelimedir (C99'dan beri); ne yazık ki, şimdiye kadar C ++ 'a dahil edilmemiştir (kötü nedenlerden dolayı C ++' a tanıtmak daha karmaşıktır). Ancak birçok derleyici bunu biraz destekliyor __restrict
.
Alt satır: Derleyici derlerken "ezoterik" kullanım durumunuzu desteklemelidir f()
ve bununla ilgili herhangi bir sorun yaşamazsınız.
İçin kullanım durumları ile ilgili bu gönderiye bakın restrict
.
const
“sizin tarafınızdan (= işlev) bu işaretçiden değişiklik yapmamanız gereken bir yükümlülük” değildir. C standardı, işlevinconst
bir döküm yoluyla kaldırılmasına ve ardından sonuç üzerinden nesneyi değiştirmesine izin verir . Esasen,const
bir nesneyi yanlışlıkla değiştirmekten kaçınmaya yardımcı olmak için programcıya sadece tavsiye ve kolaylık sağlamaktır.