Tarihsel (belki de bölümlerini yeniden yazarak), tam tersi oldu. Prototipik bir embriyonik C (belki BCPL ) çalıştıran 1970'lerin başındaki ilk bilgisayarlarda (belki de PDP-11 ) , MMU ve hafıza koruması yoktu (ki bunlar daha eski IBM / 360 ana bilgisayarlarında mevcuttu). (Literal dizeleri veya makine işleme kodu dahil) bellek her bayt hatalı program tarafından üzerine yazılır olabilir Yani (bazı değişen bir program hayal etmek bir de printf (3) biçim dizesi). Bu nedenle, değişmez dizeler ve sabitler yazılabilirdi.%
/
1975’teki bir genç olarak, 1960’lı yılların başlarında Paris’teki Palais de la Découverte müzesinde hafıza koruması olmayan bilgisayarlarda kod yazdım: IBM / 1620’nin sadece bir çekirdek hafızası vardı; Delikli bantlar üzerindeki ilk programı okumak için rakam; CAB / 500 bir manyetik tambur belleğine sahipti; Tamburun yakınındaki mekanik anahtarlardan bazı parçalar yazmayı devre dışı bırakabilirsiniz.
Daha sonra, bilgisayarlar bir miktar hafıza korumasına sahip bir tür hafıza yönetim birimi (MMU) aldı. İşlemcinin bir tür belleğin üzerine yazmasını yasaklayan bir cihaz vardı. Bu nedenle, bazı hafıza bölümleri, özellikle de kod bölümü (aka .text
segment) salt okunur hale geldi (diskten yüklenen işletim sistemi hariç). Derleyici ve bağlayıcının hazırlayıcı dizeleri bu kod segmentine koyması doğaldı ve yalnızca hazırlayıcı diziler salt okunur hale geldi. Programınız üzerine yazmaya çalıştığında, tanımsız bir davranış olarak kötüydü . Ve sanal bellekte salt okunur bir kod parçasına sahip olmak önemli bir avantaj sağlar: aynı programı çalıştıran birkaç işlem aynı RAM’i paylaşır ( fiziksel bellekbu kod bölümü için sayfalar ( Linux'ta mmap (2)MAP_SHARED
işaretine bakınız ).
Bugün, ucuz mikrodenetleyiciler bazı salt okunur belleğe (örn. Flash veya ROM) sahiptir ve kodlarını (ve değişmez dizeleri ve diğer sabitleri) orada tutarlar. Ve gerçek mikroişlemciler (tabletinizdeki, dizüstü bilgisayarınızdaki veya masaüstünüzdeki gibi) gelişmiş bir bellek yönetim birimine ve sanal bellek ve çağrı için kullanılan önbellek makinelerine sahiptir . Bu nedenle çalıştırılabilir programın (örneğin ELF'deki ) kod bölümü salt okunur, paylaşılabilir ve çalıştırılabilir bir bölüm olarak ( mmap (2) veya Linux'ta çalıştırma (2) ; BTW ld) için direktifler verebilirsiniz.eğer gerçekten istersen yazılabilir bir kod parçası almak için). Yazma veya kötüye kullanma genellikle bir segmentasyon hatasıdır .
Bu yüzden C standardı baroktur: yasal olarak (sadece tarihsel nedenlerden dolayı), edebi karakter dizileri const char[]
diziler değildir , sadece char[]
üzerine yazmak yasaktır.
BTW, birkaç mevcut dilde, dize değişmezlerinin üzerine yazılmasına izin verilir (tarihsel olarak -veya da kötü şekilde yazılabilir değişmez dizgelere sahip olan Ocaml bile, son zamanlarda 4.02'de bu davranışı değiştirmiştir ve şimdi salt-okunur dizeler vardır).
Mevcut C derleyicileri son 5 baytı (sonlandırıcı boş bayt dahil) en iyi duruma getirebilir "ions"
ve "expressions"
paylaşabilir.
Dosyasında C kodunu derlemek için deneyin foo.c
ile gcc -O -fverbose-asm -S foo.c
oluşturulan montajcı dosyası içinde ve görünüm foo.s
tarafından GCC
Sonunda , C'nin semantiği yeterince karmaşıktır ( onu yakalamaya çalışan CompCert ve Frama-C hakkında daha fazla bilgi edinin ) ve yazılabilir sabit değişmez dizgelerin eklenmesi, programları daha zayıf ve daha az güvenli hale getirirken (daha az) tanımlanmış davranış), bu nedenle gelecekteki C standartlarının yazılabilir değişmez karakterleri kabul etmesi pek olası değildir. Belki de tam tersine, onları const char[]
ahlaki olarak olması gerektiği gibi diziler haline getireceklerdir .
Ayrıca, birçok nedenden ötürü, değişken verilerin bilgisayar tarafından ele alınması (önbellek tutarlılığı), geliştirici tarafından anlaşılması için sabit verilerden daha zor olduğunu unutmayın. Bu nedenle, verilerinizin çoğunun (ve özellikle değişmez dizgelerin) değişmez kalması tercih edilir . İşlevsel programlama paradigması hakkında daha fazla bilgi edinin .
IBM / 7094'teki eski Fortran77 günlerinde, bir hata bir sabiti bile değiştirebilirdi: siz CALL FOO(1)
ve eğer FOO
2'ye atıfta bulunulan argümanı değiştirirseniz, uygulama 1'den 2'ye kadar olan diğer oluşumları değiştirmiş olabilirdi, ve bu gerçekten de bir gerçekti. yaramaz böcek, bulmak oldukça zor.