Sebuah proposal baru untuk menghadirkan fitur pemrograman kontrak ke bahasa C telah memicu diskusi yang penuh gairah di komunitas pemrograman. Proposal tersebut, yang terinspirasi dari pekerjaan kontrak C++ yang sedang berlangsung, bertujuan untuk menambahkan precondition dan postcondition ke fungsi C , namun para developer terpecah tajam mengenai apakah penambahan tersebut akan membantu atau merugikan bahasa ini.
Primitif Kontrak yang Diusulkan untuk C:
contract_assert(COND, "message")
- Mirip dengan assert yang sudah ada tetapi selalu aktif (tanpa NDEBUG)contract_assume(COND, "message")
- Menggunakan perilaku yang tidak terdefinisi melaluiunreachable()
untuk optimisasi- Prakondisi:
require: (condition)
- Diperiksa saat masuk fungsi - Pascakondisi: Diperiksa saat fungsi kembali
Komunitas Terpecah dalam Filosofi Evolusi Bahasa
Proposal ini telah mengekspos perpecahan fundamental dalam komunitas pemrograman C tentang arah masa depan bahasa tersebut. Beberapa developer berargumen bahwa C harus berevolusi untuk tetap relevan di era dimana bahasa yang aman memori seperti Rust semakin populer. Mereka menunjukkan bahwa bahasa lain telah berhasil berevolusi sambil mempertahankan identitas inti mereka.
Namun, sebagian besar komunitas sangat menentang perubahan besar pada C . Para developer ini percaya bahwa kekuatan C terletak pada kesederhanaan dan keandalannya, berargumen bahwa bahasa tersebut harus fokus pada klarifikasi perilaku undefined yang ada dan meningkatkan dokumentasi daripada menambahkan fitur baru. Mereka khawatir bahwa complexity creep dapat mengubah C menjadi bahasa lain yang sulit dikelola seperti C++ modern.
Kekhawatiran Komunitas:
- Keamanan: Perilaku yang tidak terdefinisi saat kontrak gagal versus penanganan error yang dapat diprediksi
- Kompleksitas: Risiko C menjadi sekompleks C++ modern
- Implementasi: Hanya 3 kompiler C++ berkualitas versus ratusan kompiler C
- Filosofi: Evolusi bahasa versus mempertahankan kesederhanaan tradisional C
Kekhawatiran Teknis Tentang Keamanan Implementasi
Sistem kontrak yang diusulkan sangat bergantung pada undefined behavior melalui makro unreachable()
C23 yang baru. Ketika asumsi kontrak gagal, hal tersebut memicu undefined behavior, yang memungkinkan compiler mengoptimalkan kode tetapi menciptakan risiko keamanan potensial. Para kritikus berargumen bahwa pendekatan ini menggantikan penanganan error yang dapat diprediksi dengan korupsi program yang tidak dapat diprediksi.
Implementasi teknis juga menimbulkan pertanyaan tentang utilitas praktis. Tidak seperti bahasa seperti Ada atau Eiffel yang dapat membuktikan kontrak pada compile time, proposal C tampaknya lebih fokus pada runtime checking dan optimization hints. Beberapa developer mempertanyakan apakah hal ini memberikan manfaat yang cukup untuk membenarkan kompleksitas tambahan.
Fitur C23/Masa Depan yang Diperlukan:
- Pernyataan
defer
dengandefer_return_value
untuk kondisi pasca - Operator
typeof
untuk penyalinan prototipe fungsi - Makro
unreachable()
untuk optimisasi perilaku yang tidak terdefinisi - Dukungan inlining fungsi untuk penempatan kontrak
Perdebatan Panic vs Error Handling
Titik perdebatan utama berpusat pada filosofi error handling. Sistem kontrak memperkenalkan perilaku seperti panic ke C , dimana pelanggaran kontrak menyebabkan penghentian program secara langsung daripada mengembalikan kode error. Para kritikus berargumen bahwa hal ini menghilangkan kontrol dari developer yang mungkin ingin menangani error dengan baik.
Anda sekarang telah memperkenalkan panic ke C . Dan panic itu buruk. Panic adalah ranjau darat yang menunggu beberapa keadaan yang tidak menguntungkan untuk merusak aplikasi Anda secara tak terduga, yang tidak dapat Anda kontrol karena kontrol atas penanganan error sekarang telah direbut dari Anda.
Para pendukung membantah bahwa crash di dekat sumber error dengan pesan yang jelas lebih baik daripada crash undefined behavior misterius yang terjadi jauh kemudian dalam eksekusi.
Solusi Alternatif dan Tools yang Ada
Beberapa anggota komunitas telah menunjuk pada solusi yang ada yang mengatasi kebutuhan serupa tanpa memerlukan perubahan bahasa. Beberapa menyarankan bahwa hygenic macros yang ditambahkan ke header assert.h yang ada dapat menyediakan sebagian besar fungsi yang diinginkan. Yang lain mereferensikan tools seperti fitur bounds-safety Clang atau bahasa seperti Ada / SPARK yang sudah memiliki sistem kontrak yang matang.
Diskusi tersebut juga telah menyoroti bahwa Digital Mars C++ telah menyertakan kontrak sejak awal 1990-an, menimbulkan pertanyaan tentang mengapa fitur tersebut belum mendapat adopsi yang lebih luas di ekosistem C / C++ meskipun telah tersedia selama puluhan tahun.
Perdebatan ini mencerminkan ketegangan yang lebih luas dalam pemrograman sistem antara mempertahankan kesederhanaan tradisional C dan beradaptasi dengan persyaratan keamanan modern. Seiring keamanan memori menjadi semakin penting untuk keamanan, komunitas C menghadapi keputusan sulit tentang seberapa banyak perubahan yang dapat diserap bahasa sambil tetap setia pada filosofi desain aslinya.
Referensi: Contracts for C