Satu cadangan baharu untuk membawa ciri pengaturcaraan kontrak kepada bahasa C telah mencetuskan perbincangan yang penuh semangat dalam komuniti pengaturcaraan. Cadangan ini, yang diilhamkan oleh kerja kontrak berterusan C++ , bertujuan untuk menambah prakondisi dan pascakondisi kepada fungsi C , tetapi pembangun terbahagi dengan tajam sama ada penambahan sedemikian akan membantu atau membahayakan bahasa tersebut.
Primitif Kontrak yang Dicadangkan untuk C:
contract_assert(COND, "message")
- Serupa dengan assert sedia ada tetapi sentiasa aktif (tiada NDEBUG)contract_assume(COND, "message")
- Menggunakan tingkah laku tidak ditentukan melaluiunreachable()
untuk pengoptimuman- Prasyarat:
require: (condition)
- Diperiksa pada kemasukan fungsi - Pascasyarat: Diperiksa pada pemulangan fungsi
Komuniti Terpecah Mengenai Falsafah Evolusi Bahasa
Cadangan ini telah mendedahkan perpecahan asas dalam komuniti pengaturcaraan C mengenai hala tuju masa depan bahasa tersebut. Sesetengah pembangun berhujah bahawa C mesti berkembang untuk kekal relevan dalam era di mana bahasa selamat memori seperti Rust semakin mendapat tempat. Mereka menunjukkan bahawa bahasa lain telah berjaya berkembang sambil mengekalkan identiti teras mereka.
Walau bagaimanapun, sebahagian besar komuniti menentang keras perubahan besar kepada C . Pembangun ini percaya kekuatan C terletak pada kesederhanaan dan kebolehpercayaannya, dengan berhujah bahawa bahasa tersebut harus memberi tumpuan kepada menjelaskan tingkah laku tidak ditakrifkan yang sedia ada dan menambah baik dokumentasi daripada menambah ciri baharu. Mereka bimbang bahawa kerumitan yang merayap boleh mengubah C menjadi bahasa lain yang sukar dikendalikan seperti C++ moden.
Kebimbangan Komuniti:
- Keselamatan: Tingkah laku tidak ditentukan apabila kontrak gagal berbanding pengendalian ralat yang boleh diramal
- Kerumitan: Risiko C menjadi serumit C++ moden
- Pelaksanaan: Hanya 3 pengkompil C++ berkualiti berbanding beratus-ratus pengkompil C
- Falsafah: Evolusi bahasa berbanding mengekalkan kesederhanaan tradisional C
Kebimbangan Teknikal Mengenai Keselamatan Pelaksanaan
Sistem kontrak yang dicadangkan sangat bergantung kepada tingkah laku tidak ditakrifkan melalui makro unreachable()
C23 yang baharu. Apabila andaian kontrak gagal, ia mencetuskan tingkah laku tidak ditakrifkan, yang membolehkan pengkompil mengoptimumkan kod tetapi mewujudkan risiko keselamatan yang berpotensi. Pengkritik berhujah pendekatan ini menggantikan pengendalian ralat yang boleh diramal dengan kerosakan program yang tidak dapat diramal.
Pelaksanaan teknikal juga menimbulkan persoalan mengenai utiliti praktikal. Tidak seperti bahasa seperti Ada atau Eiffel yang boleh membuktikan kontrak pada masa kompilasi, cadangan C nampaknya lebih memberi tumpuan kepada pemeriksaan masa jalan dan petunjuk pengoptimuman. Sesetengah pembangun mempersoalkan sama ada ini memberikan faedah yang mencukupi untuk mewajarkan kerumitan tambahan.
Ciri-ciri C23/Masa Depan yang Diperlukan:
- Penyata
defer
dengandefer_return_value
untuk syarat-syarat pasca - Operator
typeof
untuk penyalinan prototaip fungsi - Makro
unreachable()
untuk pengoptimuman tingkah laku tidak terdefinisi - Sokongan penyisipan fungsi untuk penempatan kontrak
Perdebatan Panik Berbanding Pengendalian Ralat
Titik perbalahan utama tertumpu kepada falsafah pengendalian ralat. Sistem kontrak memperkenalkan tingkah laku seperti panik kepada C , di mana pelanggaran kontrak menyebabkan penamatan program segera daripada mengembalikan kod ralat. Pengkritik berhujah ini menghilangkan kawalan daripada pembangun yang mungkin mahu mengendalikan ralat dengan baik.
Anda kini telah memperkenalkan panik kepada C . Dan panik adalah buruk. Panik adalah ranjau darat yang hanya menunggu beberapa keadaan malang untuk meruntuhkan aplikasi anda secara tidak dijangka, yang anda tidak dapat kawal kerana kawalan ke atas pengendalian ralat kini telah direbut daripada anda.
Penyokong membalas bahawa meruntuh berhampiran sumber ralat dengan mesej yang jelas adalah lebih baik daripada kemalangan tingkah laku tidak ditakrifkan yang misteri yang berlaku kemudian dalam pelaksanaan.
Penyelesaian Alternatif dan Alat Sedia Ada
Beberapa ahli komuniti telah menunjukkan kepada penyelesaian sedia ada yang menangani keperluan serupa tanpa memerlukan perubahan bahasa. Ada yang mencadangkan bahawa makro higienik yang ditambah kepada pengepala assert.h sedia ada boleh menyediakan sebahagian besar fungsi yang diingini. Yang lain merujuk kepada alat seperti ciri keselamatan sempadan Clang atau bahasa seperti Ada / SPARK yang sudah mempunyai sistem kontrak yang matang.
Perbincangan juga telah menyerlahkan bahawa Digital Mars C++ telah memasukkan kontrak sejak awal 1990-an, menimbulkan persoalan mengapa ciri sedemikian tidak mendapat penerimaan yang lebih luas dalam ekosistem C / C++ walaupun telah tersedia selama beberapa dekad.
Perdebatan ini mencerminkan ketegangan yang lebih luas dalam pengaturcaraan sistem antara mengekalkan kesederhanaan tradisional C dan menyesuaikan diri dengan keperluan keselamatan moden. Memandangkan keselamatan memori menjadi semakin penting untuk keselamatan, komuniti C menghadapi keputusan sukar mengenai berapa banyak perubahan yang boleh diserap oleh bahasa tersebut sambil kekal setia kepada falsafah reka bentuk asalnya.
Rujukan: Contracts for C