const, C dilinde bir nesnenin değiştirilebilirliğini kısıtlamaya yarar. Fonksiyon parametreleri ile çalışırken, verileri kazara değiştirilmekten korumaya yardımcı olur. Beyanda en önemli farklılık, const modificatorünün neye atanmış olduğuna ve işaretçinin yanında nereye yerleştirildiğine bağlıdır.
Farklı beyan örnekleri:
void func(const int *ptr); // sabit int'e işaretçi void func(int * const ptr); // sabit işaretçi int için void func(const int *const ptr); // sabit işaretçi sabit int için
const int *ptr — veriler değiştirilemez, kendisi ile işaretçi yeniden atanabilir.int *const ptr — veriler değiştirilebilir, ancak işaretçi yeniden atanamaz.const int *const ptr — ne veriler ne de işaretçi, fonksiyon içinde değiştirilemez.Const kullanımıyla ilgili doğru kullanımlar:
void print_array(const int *arr, size_t n) { for (size_t i = 0; i < n; ++i) { printf("%d\n", arr[i]); // arr[i] = 10; // hata: const verileri değiştirme denemesi } }
Soru: Konstant bir değişkenin adresini sıradan bir işaretçiye atayabilir miyim?
Beklenen yanlış cevap: "Evet, işaretçi beyanında const kaldırılırsa, derleyici izin verir."
Doğru cevap: "Const düşürme" yalnızca açık tür dönüştürmesi (casting) ile mümkündür, ancak bu, bir const olarak beyan edilen nesneyi değiştirmeye çalışırken tanımsız davranışa yol açar. Bunu yapmak doğru değildir; bu, const semantiğini ihlal eder ve çalışma zamanı hatalarına yol açar.
Örnek:
const int x = 5; int *ptr = (int*)&x; *ptr = 10; // UB: const-nesneyi değiştirme
Hikaye
Büyük bir projede, bir programcı const korumasını aşmaya çalışarak, const işaretçiyi normaline çevirip, read-only bellek segmentinde verileri değiştirdi. Bazı platformlarda bu, programın sonlanmasına (segmentation fault) yol açtı, diğerlerinde ise hata görülmedi ve hata ayıklaması zor hatalara neden oldu.
Hikaye
Bir dizi ile çalışma kütüphanesinde, geliştirici parametreleri const olarak beyan etmeyi unuttu. Bu durumda, geçersiz bir fonksiyon çağrısı, orijinal verileri yanlışlıkla değiştirdi ve dizi durumunun senkronizasyonunu bozarak sonraki işleme bloklarında ciddi hatalara yol açtı.
Hikaye
Başka bir kütüphaneye geçilen callback-fonksiyonunu yazarken, giriş tamponu için const belirtmeyi unuttular. Kütüphane, sabit dizgedeki verileri değiştirmeye çalıştı ve bu, bazı işletim sistemlerinde çökme ile sonuçlandı; problemin kaynağını belirlemek ise uzun sürücü oldu.