- safe_c.h adalah file header kustom sepanjang 600 baris yang menambahkan fitur keamanan dan kemudahan ala C++ dan Rust ke bahasa C, dan digunakan dalam implementasi grep yang aman terhadap thread tanpa kebocoran memori (cgrep)
- Melalui RAII, smart pointer, dan atribut cleanup otomatis, pengelolaan resource diotomatisasi tanpa perlu pemanggilan
free() manual
- Dengan vector, view, tipe Result, dan makro kontrak, buffer overflow, penanganan error, dan verifikasi prasyarat dapat dilakukan dengan aman
- Dengan pelepasan mutex otomatis, makro spawn thread, dan optimasi prediksi percabangan, keamanan tetap terjaga sambil mempertahankan konkurensi dan performa
- Hasilnya, ini membuktikan kemungkinan menulis kode C tanpa kebocoran dan segfault dengan performa yang sama (setara tingkat
-O2)
Ikhtisar safe_c.h
- safe_c.h adalah file header yang membawa fitur C++ dan Rust ke dalam kode C
- Bahkan pada compiler yang tidak mendukung atribut C23
[[cleanup]] (seperti GCC 11, Clang 18), ia tetap menyediakan perilaku RAII (pembersihan otomatis) yang sama
- Makro
CLEANUP(func) secara otomatis melepaskan resource saat fungsi berakhir
- Makro
LIKELY() dan UNLIKELY() untuk optimasi prediksi percabangan pada hot path
Manajemen memori: UniquePtr dan SharedPtr
- UniquePtr adalah smart pointer kepemilikan tunggal yang otomatis memanggil
free() saat scope berakhir
- Jika dideklarasikan dengan makro
AUTO_UNIQUE_PTR(), memori tetap dibebaskan otomatis meski terjadi error atau return lebih awal
- SharedPtr adalah struktur dengan reference counting otomatis yang menghancurkan resource secara otomatis saat referensi terakhir dilepas
shared_ptr_init() dan shared_ptr_copy() menangani kenaikan/penurunan referensi secara otomatis
- Digunakan untuk mengelola struct yang dibagikan secara aman antar-thread
Pencegahan buffer overflow: Vector dan View
- Makro DEFINE_VECTOR_TYPE() membuat vector yang dapat berkembang otomatis dan type-safe
- Realokasi, pengelolaan kapasitas, dan pembersihan ditangani secara otomatis
- Jika dideklarasikan dengan
AUTO_TYPED_VECTOR(), resource dibebaskan otomatis saat scope berakhir
- StringView dan Span adalah struct referensi non-owning untuk menangani slice string dan array tanpa
malloc tambahan
DEFINE_SPAN_TYPE() mendefinisikan Span per tipe
- Dilengkapi pemeriksaan batas untuk menjamin akses array yang aman
Penanganan error: tipe Result dan RAII
- Struct Result adalah tipe nilai balik yang membedakan sukses/gagal mirip
Result<T, E> milik Rust
DEFINE_RESULT_TYPE() membuat struct hasil per tipe
RESULT_IS_OK() dan RESULT_UNWRAP_ERROR() memungkinkan penanganan error yang jelas
- Dikombinasikan dengan atribut
CLEANUP, resource dibebaskan otomatis saat fungsi selesai
- Makro
AUTO_MEMORY() membersihkan memori hasil malloc secara otomatis
Kontrak dan string aman
- Makro requires() / ensures() menyatakan kondisi sebelum dan sesudah fungsi
- Jika gagal, pesan error yang jelas akan ditampilkan
- safe_strcpy() adalah fungsi copy dengan pemeriksaan ukuran buffer, untuk mencegah overflow
- Jika gagal, fungsi mengembalikan false sehingga penanganan error tetap aman
Konkurensi: unlock otomatis dan makro thread
- Fungsi pelepasan mutex otomatis berbasis
CLEANUP mencegah deadlock
pthread_mutex_unlock() dipanggil otomatis saat scope berakhir
- Makro
SPAWN_THREAD() dan JOIN_THREAD() menyederhanakan pembuatan dan join thread
- Digunakan dalam implementasi thread pool pemrosesan file pada cgrep
Optimasi performa
- Makro
LIKELY() / UNLIKELY() menyediakan prediksi percabangan untuk hot path
- Efek optimasi setingkat PGO dapat diperoleh bahkan pada build
-O2
- Meski fitur keamanan ditambahkan, tidak ada penurunan performa
Kesimpulan
- cgrep yang menggunakan safe_c.h terdiri dari 2.300 baris kode C, dan menghilangkan lebih dari 50 pemanggilan
free() manual
- Tetap mempertahankan assembly dan kecepatan eksekusi yang sama, sambil mewujudkan kode C yang aman tanpa kebocoran memori dan segfault
- Ini adalah contoh yang menggabungkan keamanan modern sambil mempertahankan kesederhanaan dan kebebasan C
- Penulis menyebutkan bahwa tulisan berikutnya akan membahas alasan cgrep bisa lebih dari 2 kali lebih cepat dari ripgrep dan menggunakan memori 20 kali lebih sedikit
- safe_c.h disebut cocok untuk proyek baru, meski juga disinggung bahwa pendekatan berbasis makro dapat meningkatkan kesulitan debugging
- Verifikasi akurasi dan keamanan dilakukan dengan berbagai static analyzer (GCC analyzer, ASAN, UBSAN, Clang-tidy, dll.)
Belum ada komentar.