- Scylla mengusulkan jalur untuk secara bertahap menstrukturkan C asli agar dapat langsung dikompilasi menjadi Rust yang aman, alih-alih memindahkan C lama ke unsafe Rust lalu memperbaikinya
- Targetnya adalah subset C aplikatif yang mencakup pemrosesan data, operasi pointer, alur kontrol terstruktur, dan kode portabel; kode yang bergantung pada
goto, cast integer-pointer, trik pointer, bitfield, dan untagged union dikecualikan - Transformasinya terdiri dari 2 tahap: menurunkan Clang AST menjadi Mini-C, lalu memindahkannya ke safe Rust; perilaku halus C seperti promosi integer, konversi implisit, ekspresi assignment, serta increment prefix/postfix dibuat eksplisit
- Aritmetika pointer yang paling sulit diubah menjadi pemecahan berbasis Rust slice dan
split_at_mut/split_at, sekaligus menangani inferensi mutabilitas, derivasi trait, serta pemilihanBoxdan borrow - Mereka mengevaluasi SymCrypt Windows, HACL★, algoritme kompresi inti bzip2, parser/serializer CBOR EverParse, serta sebagian Microsoft FrodoKEM; selama transformasi juga ditemukan undefined behavior pada bzip2 dan FrodoKEM
Jalur transisi C→Rust yang dipilih Scylla
- Motivasi untuk memindahkan kode C lama ke Rust berawal dari masalah keamanan memori
- Riset Google dan Microsoft memperkirakan 70% kerentanan keamanan berkaitan dengan penanganan memori yang keliru
- Perusahaan dan pemerintah mendorong penggunaan bahasa yang aman memori seperti Rust untuk sistem yang kritis terhadap keselamatan
- Rust memiliki keunggulan jelas untuk kode baru, tetapi sulit menulis ulang seluruh kode C industri yang sudah diuji dan di-debug
- Tool konversi otomatis C→Rust yang ada umumnya menghasilkan unsafe Rust agar dapat mendukung seluruh C
- Mengizinkan idiom ala C seperti unchecked pointer atau transmutation di Rust
- Jaminan keamanan memori statis hilang, sehingga tujuan memakai safe language menjadi lebih lemah
- Workflow umum adalah menjadikan output unsafe Rust sebagai titik awal, lalu melakukan refactoring berulang menjadi Rust yang aman
- Ada analisis statis yang diusulkan untuk mengganti raw pointer dengan borrow safe Rust, atau memulihkan abstraksi Rust dari representasi level rendah
- Tool refactoring tersebar, dan dukungan
c2rust refactorjuga dihentikan pada 2022
- Alih-alih memperbaiki unsafe Rust yang dihasilkan, Scylla memilih cara menstrukturkan kode C asli itu sendiri secara bertahap agar dapat dikompilasi menjadi safe Rust
Subset C yang didukung dan pola yang dikecualikan
- Tujuan Scylla adalah menghasilkan transformasi yang dapat diprediksi dan kode Rust yang dekat dengan C asli
- Target yang didukung adalah subset C aplikatif
- Kode yang memanipulasi dan memproses data
- Kode yang menggunakan aritmetika pointer
- Kode dengan alur kontrol terstruktur
- Kode portabel
- Codebase yang bergantung pada pola berikut tidak didukung
goto- Penggunaan representasi objek melalui cast integer-pointer
- Trik pointer
- Bitfield
- Untagged union
- Developer dapat menerapkan rewrite dan anotasi terarah pada source C agar dapat dipahami Scylla
- Pola aliasing yang tidak cocok dengan Rust borrow checker dapat ditulis ulang
- Developer dapat memberi informasi kepada Scylla bahwa tagged union harus diterjemahkan menjadi ADT level tinggi
Mini-C: bahasa perantara yang mengurangi ambiguitas C
- Scylla berangkat dari AST frontend Clang, lalu pertama-tama mentransformasikannya ke bahasa bernama Mini-C
- Mini-C menangani branch, loop, pointer, dereference, dan pengambilan alamat seperti C, tetapi memiliki semantik “no-surprises”
- Semua integer memiliki lebar tetap
- Integer promotion dan integer conversion C direpresentasikan sebagai cast eksplisit
- Untyped pointer seperti
void *tidak diizinkan
- Berbeda dari C, Mini-C adalah bahasa ekspresi
- Assignment tidak mengembalikan nilai
- Sintaks C seperti
e1 = e2 = e3danp[i++]di-desugar di Mini-C - Ekspresi pengujian pada loop dan conditional harus bertipe
bool, bukanintseperti di C
- Saat memindahkan typed AST Clang ke typed AST Mini-C, perilaku implisit C dibuat eksplisit
- Ekspresi kondisi disesuaikan menjadi
bool - Indeks array disesuaikan menjadi
size_t - Konversi implisit pada argumen pemanggilan fungsi dan sisi kanan assignment diubah menjadi cast eksplisit
- Pada operasi aritmetika, usual arithmetic conversions dari standar C direfleksikan
- Ekspresi kondisi disesuaikan menjadi
- Transformasi mengasumsikan kode C portabel dan tidak bergantung pada model data C
- Misalnya, kode yang perilakunya berubah tergantung apakah
longberukuran 4 byte atau 8 byte tidak diharapkan - Implementasi mendeteksi model data arsitektur target pada configure-time dan mengubah
unsigned intmenjadi tipe lebar tetap sepertiuint32_t
- Misalnya, kode yang perilakunya berubah tergantung apakah
Sintesis ADT dan tuple
- Mini-C menyediakan ADT, tuple, dan pattern matching dengan level yang lebih tinggi daripada C
- Tagged union diterjemahkan menjadi ADT melalui anotasi
- Bentuk targetnya adalah struktur seperti
{ int tag; union { t0 case0; ...; tn caseN }} - Nilai tag berada dari 0 hingga N, dan diasumsikan nilai tag sesuai dengan urutan case union
- Bentuk targetnya adalah struktur seperti
- Scylla mengubah tipe tagged union yang dianotasi menjadi tipe variant
- Saat membuat nilai, Scylla memeriksa apakah
.tag = idan.casej = ecocok - Jika cocok, nilai tersebut diubah menjadi nilai constructor terkait
- Jika payload dan tag tidak cocok, ia tidak diterjemahkan ke Mini-C
- Saat membuat nilai, Scylla memeriksa apakah
- Akses field tagged union aman hanya jika status tag saat ini diketahui
- Scylla mengenali pola seperti
if (x.tag == i) { ... x.casei }atauswitch - Ini diubah menjadi bentuk
match x with | Ci v -> ... - Akses ke union case lain dianggap invalid dan menghasilkan error transformasi
- Scylla mengenali pola seperti
- Tuple juga dapat disintesis melalui anotasi
- Struct dengan
nfield diubah menjadi tuple n-ary - Akses field berubah menjadi akses field tuple
- Tuple memiliki tipe secara struktural sehingga dapat memperoleh manfaat dari mut-polymorphism
- Struct dengan
Transformasi dari Mini-C ke safe Rust
- Mini-C menyediakan representasi program C dengan anotasi tipe lengkap, lalu ditransformasikan menjadi safe Rust
- Ada tiga kesulitan utama
- Menghapus aritmetika pointer C
- Mengeksplisitkan mutabilitas dan aliasing
- Menyediakan struktur idiomatis Rust seperti trait secara otomatis
- Transformasi tipe pointer rumit karena perbedaan representasi pointer di Rust
- Rust membedakan
Box<T>dan&T - Pointer elemen tunggal dan pointer multi-elemen juga dibedakan, misalnya
&Tdan&[T] - Array Rust adalah value dan tidak otomatis decay menjadi pointer seperti di C
- Rust membedakan
- Strategi dasarnya adalah mengompilasi semua pointer type C menjadi slice borrow Rust
&[T]- Pointer stack maupun heap secara default menjadi slice borrow
- Pointer elemen tunggal maupun multi-elemen juga secara default menjadi slice borrow
- Mutabilitas diinferensikan otomatis pada tahap terpisah
- Scylla menerjemahkan sebagian pointer menjadi
Box<T>melalui heuristik dan anotasi manual- Fungsi seperti
T *create()yang dianggap fresh allocation dan tidak memiliki referensi global dapat diterjemahkan menjadifn create() -> Box<T> - Analisis ini diterapkan secara rekursif dengan metode fixed point hingga ke dalam definisi struct dan variant
- Struct yang masih memiliki borrow akan memiliki lifetime parameter
- Fungsi seperti
Batasan transformasi Box, slice, dan array
- Karena Rust memerlukan konversi eksplisit antara array, slice borrow, dan
Box, transformasi Rust Scylla juga bekerja secara type-directed - Aturan transformasi menyisipkan coercion yang mengubah array atau boxed slice menjadi slice borrow
- Array menjadi slice borrow dalam bentuk seperti
&x[..] - Boxed slice dapat dikonversi menjadi borrow
- Array menjadi slice borrow dalam bentuk seperti
- Transformasi arah sebaliknya juga memungkinkan
- Slice atau array dapat dipromosikan menjadi heap allocation dan diubah menjadi
Box<[T]>
- Slice atau array dapat dipromosikan menjadi heap allocation dan diubah menjadi
- Transformasi arah sebaliknya ini dapat menimbulkan perbedaan semantik penyalinan
- Di C, array dan pointer dapat menunjuk ke memori yang sama
- Di Rust,
Box::new(x)dapat membuat copy darix - Array tipe dasar seperti array integer tidak dapat opt out dari trait
Copy, sehingga Rust dapat melakukan penyalinan diam-diam
- Jika transformasi seperti ini terjadi, Scylla menghapus variabel asli dari environment agar penggunaan berikutnya dilarang
- Jika program C asli terus menggunakan variabel tersebut, akan terjadi error transformasi
- Developer perlu memperbaiki source C sebelum transformasi agar maksudnya lebih jelas
Mengubah aritmetika pointer menjadi pemecahan Rust slice
- Program C sering tidak hanya mengakses array dengan satu base pointer, tetapi juga membagi array menjadi chunk atau menelusurinya sambil mempertahankan pointer posisi saat ini
- Rust tidak mengizinkan aritmetika pointer sembarang, dan menyediakan cara membagi slice dengan
split_at_mutatausplit_atsplit_at_mutadalah primitive yang melepaskan kepemilikan slice asli dan memperoleh dua sub-slice- Ini mempertahankan invariant Rust bahwa mutable data harus memiliki owner yang unik
- Scylla memperkenalkan split tree untuk menyelaraskan aritmetika pointer C dengan cara pemecahan Rust
- Setiap pointer C dipetakan ke satu split tree
- Split tree berubah secara flow-dependent
- Split tree melacak akses pointer C pada titik program tertentu harus diubah menjadi akses slice Rust yang mana
- Karena pointer C tidak memiliki informasi panjang, Scylla mengasumsikan chunk tidak saling tumpang tindih
- Jika memang dimaksudkan tumpang tindih, pemeriksaan tipe Rust tidak dapat lolos, dan developer harus menulis ulang kode C
- Agar transformasi dapat diprediksi, proses dilakukan secara forward dan menghindari backtracking
- Dalam contoh, array 32 byte
abcddibagi menjadi empat area limb berukuran 8 byte- Di C, aritmetika pointer digunakan tidak dalam urutan kiri-ke-kanan, seperti
abcd + 0,abcd + 16,abcd + 8,abcd + 24 - Transformasi Rust mempertahankan riwayat pemanggilan
split_at_mutsebagai split tree untuk menemukan sub-slice yang benar
- Di C, aritmetika pointer digunakan tidak dalam urutan kiri-ke-kanan, seperti
Target evaluasi dan undefined behavior yang ditemukan
- Implementasi Scylla menggunakan Clang untuk menerima kode C lama sebagai input dan menghasilkan safe Rust
- Target evaluasi mencakup bagian dari beberapa proyek C yang ada
- Sebagian SymCrypt di Windows
- Sebagian pustaka kriptografi HACL★
- Bagian inti dari algoritme kompresi bzip2
- Parser dan serializer binary CBOR dari pustaka EverParse
- Implementasi primitive kriptografi post-quantum FrodoKEM dari Microsoft
- Kasus-kasus ini menunjukkan bahwa subset C aplikatif Scylla dapat mencakup berbagai aplikasi yang sensitif terhadap keamanan
- Dalam proses transformasi, mereka juga mengidentifikasi dan melaporkan undefined behavior yang ada pada kode C asli bzip2 dan FrodoKEM
1 komentar
Komentar Hacker News
Penting untuk dicatat bahwa pekerjaan ini ditujukan pada “basis kode C yang sudah diverifikasi secara formal”
Kode C sistem pada umumnya tidak diverifikasi secara formal, jadi ini adalah cerita yang cukup berbeda
Misalnya, pointer yang tadinya menunjuk ke array C di stack bisa diterjemahkan di Rust menjadi pointer yang memiliki salinan heap baru sebagai
Box<[u8]>. Jika kode aslinya bergantung pada fakta bahwa pointer tersebut benar-benar menunjuk ke array asli, kode hasil terjemahan bisa diam-diam berjalan salahDalam fitur terjemahan otomatis subset C++ aman terhadap memori di proyek saya, scpptool, hal seperti ini akan ditangani dengan memindahkan array ke tipe pengganti dan iterator agar makna aslinya tetap terjaga
Mungkin proyek OP memang hanya menangani C yang mudah diubah menjadi Rust aman, tetapi mengingat tingkat kesulitannya, hasil ini tetap patut dihargai dan tampak punya kegunaan sampai batas tertentu
Sejak awal mereka sebenarnya tidak menerjemahkan C nyata, melainkan mengubah sisi kompiler agar kode yang ditulis dalam F* mengeluarkan Rust. Mereka tidak berhadapan dengan C dunia nyata yang kompleks, paling-paling hanya menangani Mini-C terbatas yang mungkin dikeluarkan kompiler mainan
Di tulisan aslinya juga disebutkan bahwa jika program C asal terlalu bergantung pada
x, terjemahan akan menghasilkan error dan meminta programmer memodifikasi sumbernya; ini berarti mereka berharap C tersebut sudah ditulis dalam gaya yang memuaskan borrow checker RustIni terasa seperti ungkapan akademik untuk “Gambar 4 menyajikan aturan yang indah, tetapi implementasi nyatanya bergantung pada banyak trik”
Lebih buruk lagi, jika ada overlap yang bisa dibedakan secara statis maka akan terjadi error kompilasi, dan jika tidak maka kode Rust bisa panic saat runtime. Mengubah program C yang diverifikasi secara formal menjadi program Rust yang “sekarang bisa crash” terasa aneh
Menyebut HACL* sebagai basis kode C yang sudah diverifikasi secara formal juga tidak akurat. HACL* memang dikompilasi ke C, tetapi bukan pustaka C; ia ditulis dalam bahasa yang sepenuhnya berbeda
Judul yang jujur seharusnya kira-kira: “Mengompilasi subset F* ke Rust yang sebagian aman, dengan formalisasi sebagian”
Pada tahun 2002, para peneliti menerbitkan makalah tentang Cyclone, dialek C yang aman, dan saat memindahkan kode C ke Cyclone secara manual mereka menemukan bug keamanan pada kode C yang sudah ada
Transformasi C seperti ini, baik manual maupun otomatis, bukan hanya berpotensi meningkatkan adopsi bahasa yang lebih aman, tetapi juga mengungkap bug lama
[1] https://www.researchgate.net/profile/James-Cheney-2/publicat...
Banyak ide dari Cyclone masuk ke Rust, dan kodenya masih bisa dibuat jalan dengan usaha, tetapi tidak langsung bisa dibangun di platform 64-bit modern
http://cyclone.thelanguage.org
Saya pernah memakai C2Rust sebagai langkah awal untuk mem-porting beberapa proyek, termasuk proyek C, ke Rust, dan mendapat beberapa kesimpulan
unsafe, bug sering kali lebih cepat terungkap berkat batasan kuat Rust, seperti pemeriksaan batas dan signature yang ketatMeski begitu, alat tetap penting untuk porting, dan semakin alatnya berkembang, prosesnya akan makin mulus
Caranya adalah merepresentasikan memori sebagai array dan memperlakukan pointer sebagai indeks ke array tersebut. Dengan begitu, perilaku C seperti aritmetika pointer tanpa pemeriksaan atau union bisa diekspresikan tanpa harus melawan borrow checker, dan maknanya tetap terjaga. Teknik serupa juga sudah lama dipakai dalam C→Java
Tentu saja nilai dari transformasi seperti ini agak meragukan. Pada dasarnya ini mirip mengompilasi C ke wasm tetapi lebih lambat, dan walaupun kode hasilnya secara teknis “aman”, masalah seperti buffer overflow yang menciptakan state salah atau dangling pointer yang memungkinkan akses data dalam konteks yang seharusnya tidak diizinkan tetap ada
Saya penulisnya. Rasanya akan membantu jika saya merangkum beberapa hal yang muncul dari beberapa thread
unsafe Rustuntuk bagian yang tidak cocokYang benar-benar membuat saya penasaran adalah mengapa ini harus dilakukan
Jika ini adalah teknologi yang benar-benar bisa mengonversi aplikasi industri dari C ke Rust, tampaknya itu juga bisa mempermudah membentengi aplikasi C yang sudah ada. Cukup buat analisis yang bisa dimasukkan ke alat yang sudah ada seperti penganalisis statis atau pembangkit uji
Demikian juga, kita bisa membuat wrapper yang aman sehingga kode baru dapat ditulis dalam Rust di samping C yang sudah diverifikasi. Kode baru mendapat manfaat Rust, kode lama dipastikan aman, dan antarmukanya juga menjadi lebih aman
Penerjemah penuh mungkin ideal. Dalam jangka panjang, memang bagus bila codebase hanya punya satu bahasa. Tetapi untuk C/C++ yang sudah ada, kebutuhan terbesar tetaplah pengamanan sekali klik dengan sedikit false positive. Mungkin juga dimungkinkan untuk secara otomatis memperbaiki struktur buruk di dalam C, seperti alat compiler milik Google atau Mayhem dari ForAllSecure
Mungkin karena program tersebut bergantung pada undefined behavior atau unspecified behavior, atau karena jika pemeriksaan keamanan yang layak ditambahkan, rentang input yang diizinkan menyusut terlalu banyak hingga menjadi tidak berguna
Menerjemahkannya ke bahasa yang aman secara objektif lebih baik dalam kasus seperti ini karena ekspresivitas input dapat dipertahankan sambil menjamin perilaku yang benar saat dijalankan secara statis
Gagasan tentang “C yang sudah terbukti di lapangan” juga sulit dikatakan benar-benar ada, seperti yang ditunjukkan oleh banyaknya kerentanan fatal. Yang benar-benar ada hanyalah C yang cukup sering bekerja cukup baik sehingga tampak berguna
Kode lama diasumsikan aman karena beruntung, bukan karena terbukti. “Bukti” punya makna khusus, terutama dalam konteks makalah seperti ini, dan mayoritas besar kode C tidak terbukti menurut standar matematis yang ketat. Sebaliknya, sistem tipe Rust telah terbukti benar secara matematis
Penerjemah penuh bergantung pada apa yang rela Anda korbankan. Jika Anda rela mengorbankan performa, rentang input, rentang output, keterbacaan kode, dan sebagainya, mungkin sampai taraf tertentu itu bisa dilakukan; tetapi begitu Anda mulai menginginkan penerjemah yang sound dan complete di semua aspek itu, masalah akan muncul
Kalau diterjemahkan ke Rust secara naif, bukankah hasilnya akan mencampur bagian yang aman dan bagian
unsafe? Kalau begitu, tampaknya pekerjaan manual cukup memeriksa keamanan areaunsafesaja. Mirip seperti saat menulis Rust dari awalJika 90% hasilnya bukan
unsafe, itu tampak cukup menguntungkanunsafe Rusttingkat rendahOpenJPEG diketahui mengalami segfault pada kasus uji tertentu, dan ketika uji itu dijalankan pada versi Rust, segfault juga terjadi pada kode Rust yang sesuai di lokasi yang sama. Setidaknya berarti tetap kompatibel
Tetapi pendekatan itu adalah jalan buntu. Untuk benar-benar maju, penerjemah harus mengenali idiom umum C dan mengangkatnya ke bentuk yang alami dalam bahasa target. Jika “dikompilasi” ke Rust, hasilnya menjadi Rust yang mengerikan, penuh dengan pemanggilan fungsi manipulasi pointer gaya C yang tidak aman
Masalah pengangkatan terbesar sebagian besar berkaitan dengan pointer. Hasil paling menjanjikan dari makalah ini adalah ditemukannya cara mengubah aritmetika pointer C menjadi slice Rust. Slice bisa melakukan sebagian besar hal yang dilakukan aritmetika pointer C, dan sekarang seseorang telah mengotomatisasi terjemahan itu. Aritmetika pointer yang tidak bisa diterjemahkan seharusnya dipandang sangat mencurigakan
Berguna jika Anda menganggap pointer mentah yang menunjuk ke array di C secara implisit memiliki panjang. Panjang itu tidak terlihat di sumber C, tetapi ada di suatu tempat sebagai fungsi dari state program. Bisa berupa konstanta, ukuran permintaan
malloc, atau parameter fungsi. Bagi programmer pemeliharaan, biasanya tidak terlalu sulit menemukan panjang arrayIni mungkin masalah yang cocok untuk LLM. Misalnya, tanyakan “lihat kode ini dan temukan berapa panjang array
foo”, lalu biarkan penerjemah non-LLM memandu konversi Rust. Jika LLM salah, Rust akan menghasilkan kesalahan indeks atau memiliki array yang terlalu besar, tetapi tetap tidak menjadi tidak aman. Idiom informasi ukuran array di C cukup terstruktur sehingga sebagian besar kasus mestinya bisa ditebak dengan benar. Terutama karena LLM juga bisa membaca komentarunsafe. Karena ia akan memakai pointer mentah di mana-mana alih-alih referensiKode C tidak ditulis dengan mempertimbangkan model aliasing Rust dan batasan borrow checker, jadi sulit menerjemahkannya menjadi referensi
Ini hanya mengompilasi subset C yang sangat kecil. Dalam praktiknya, mungkin terlalu kecil sampai nyaris tidak berguna
Ekspektasi terhadap pendekatan seperti ini rendah. Pasti akan menabrak batas dari apa yang bisa dilakukan dengan analisis statis kode C. Lagi pula, memilih Rust sebagai target membuat masalahnya jadi lebih sulit tanpa perlu. Model kepemilikan Rust terlalu berbeda dari cara program C nyata bekerja
Misalnya, buffer di C tentu punya panjang, tetapi di C panjang itu tidak secara eksplisit terikat pada pointer. Jadi penerjemah harus menyimpulkan bagaimana program C melacak panjangnya lalu mengubahnya menjadi slice. Bahkan jika panjangnya ada di variabel eksplisit pun tidak mudah, dan akan lebih rumit jika dihitung atau dinyatakan dalam bentuk “pointer satu langkah setelah akhir”
Pola C seperti
bool should_free_this_pointerjuga bisa dipindahkan ke enumOwned/Borroweddi Rust, tetapi harus disimpulkan alokasi mana yang terhubung ke boolean mana, dan di mana batas aman yang sebenarnya untuk varian yang dipinjamMeski begitu, saya setuju bahwa membuat Rust yang idiomatis dari C arbitrer akan sulit. Katakanlah hasilnya hanya akan “kurang lebih benar”
Saya penasaran bagaimana ini dibandingkan dengan fitur konversi C milik Zig
Zig tampaknya unggul dalam menciptakan lingkungan campuran: kode baru ditulis dalam Zig, kode lama tetap di C, lalu dilakukan konversi atau interop, bahkan sekaligus berperan sebagai kompiler C
Pasti ada alasan yang sangat bagus mengapa para maintainer kernel Linux tidak melihat Zig sebagai pengganti C alih-alih Rust. Saya tidak cukup paham untuk menebak, jadi akan bagus jika orang yang lebih tahu bisa menjelaskan
Saya bukan maintainer kernel, tetapi jika menebak dua alasan besar Rust dipilih ketimbang Zig, mungkin karena jaminan saat kompilasi yang diberikan bahasanya lebih baik dan laju adopsinya juga lebih cepat
Perusahaan-perusahaan besar di industri sedang banyak berupaya menyediakan kode native Rust untuk API atau binding Rust yang dipelihara. Para pengembang Windows juga sedang menulis ulang sebagian kernel mereka dalam Rust. Ini sudah menjadi gerakan yang berlangsung cukup lama, dan saya harap tidak berhenti
Para maintainer mungkin merasa Zig tidak memberi cukup keuntungan dibanding C. Banyak dari mereka bahkan masih menentang Rust
Zig jauh lebih baik dalam interoperabilitas dengan C dibanding Rust, tetapi tidak aman memori dan juga belum stabil. Adopsi Zig di dunia C kemungkinan akan cukup meningkat, tetapi saya rasa sulit melihatnya sebagai pesaing langsung Rust
Di daerah saya, tidak ada yang mengadopsi Rust, dan orang-orang C++ tetap bertahan di C++. Awalnya memang ada sedikit minat pada Rust, tetapi di perusahaan mana pun yang saya tahu, Rust tidak pernah benar-benar mapan. Mungkin alasannya mirip dengan Go yang tumbuh besar di perusahaan-perusahaan muda, tetapi tidak banyak masuk ke perusahaan Java/C# tradisional. Meskipun masuk akal secara teknis, ini adalah tantangan manajemen perubahan yang sangat besar
Zig memang mendapat momentum untuk program yang tidak memerlukan alokasi memori dinamis, tetapi di luar itu tidak banyak
Masih ada perubahan yang rutin mematahkan kompatibilitas, dan meskipun ini bagus untuk Zig saat ini, itu tidak baik untuk codebase raksasa dan berumur panjang seperti Linux. Bug kompiler juga masih muncul
Saya bilang ini sebagai orang yang secara umum menyukai arah Zig
Saya penasaran apakah alat seperti
C2Rustbisa memanfaatkan ini untuk menghasilkan kode yang benar secara formalSaya juga penasaran seberapa banyak pekerjaan manual yang dilakukan para penulis, atau apakah mereka menjalankan sesuatu untuk menghasilkan kode Rust. Jika ya, saya tidak tahu di mana kode yang menghasilkan Rust itu, dan saya juga tidak melihat tautan ke repositori sumbernya
Jika pustaka C-nya berfungsi, artinya bukan terbukti formal bebas masalah tetapi sebagian besar berjalan dengan baik, saya penasaran mengapa tidak menerjemahkannya memakai
unsafe RustMenurut saya ini tetap bernilai karena secara umum Rust masih kekurangan pustaka. Pada akhirnya ini tidak jauh berbeda dari memakai dll/so yang ditulis dalam C, yang dalam situasi tertentu juga bisa saja tidak aman