Rust: mendukung bidang bit untuk interop C

Dibuat pada 22 Agu 2013  ·  14Komentar  ·  Sumber: rust-lang/rust

Beberapa C API memiliki struct yang menggunakan bitfield, dan ini agak rumit untuk digunakan dari rust sekarang. Mungkin kita harus memiliki semacam dukungan untuk ini, atau setidaknya makro yang menanganinya.

Ini telah muncul secara khusus dengan Azure yang digunakan di Servo.

Komentar yang paling membantu

Saya baru saja menemukan masalah ini saat membaca tentang Rust. Saya ingin tahu tentang bitfield karena saya melakukan banyak pengembangan kode C/C++ yang disematkan dan kami menggunakan bitfield untuk mengekspresikan status perangkat yang terhubung dengan UART. Statusnya cukup besar tetapi berkat bitfields, itu tidak terlalu buruk. Sangat bersih untuk menandai boolean, bilangan bulat kecil tertentu dan enum sebagai satu hingga beberapa bit karena batasan memori yang rendah. Saya tidak yakin apakah Rust ingin berjalan pada perangkat dengan rentang memori 4KB - 16KB tetapi saya tidak akan menggunakan Rust jika itu mengharuskan saya menggunakan makro untuk mendapatkan bendera bit tunggal. Bitfields memungkinkan kode tingkat yang sangat tinggi di mana makro membuat mengasapi tidak dapat dibaca. Di mana kompatibilitas penyelarasan ABI/spesifik diperlukan, tentu saja makro mungkin menjadi satu-satunya pilihan. Mungkin proyek seperti Servo atau mesin Javascript masa depan di Rust mungkin secara internal menggunakan bitfield untuk menghemat memori dalam kasus tertentu.

Semua 14 komentar

Tampaknya tak terhindarkan. Saya lebih suka mencoba rute makro terlebih dahulu.

Tampaknya tidak terelakkan bagi saya ... Saya merasa seperti kita bisa baik-baik saja menggunakan uints dan masking eksplisit. Beberapa makro untuk mendukung bitset tentu saja akan baik-baik saja. Saya menduga bahwa tata letak bitfield dilakukan sepenuhnya dalam dentang, bukan LLVM, meskipun saya bisa saja salah, yang akan membuat ini cukup sulit untuk kami dukung.

Agar adil, saya tidak pernah mengerti daya tarik bitfield bahkan di C. Itu selalu tampak seperti menyerahkan kendali atas tata letak dan penyembunyian dan yang lainnya ke kompiler, tetapi Anda hanya menggunakannya ketika Anda sangat peduli dengan detailnya. -- tepatnya ketika saya lebih suka tahu persis apa yang terjadi.

Kernel Linux (dan banyak perpustakaan) menghindari bitfield secara umum, karena pembuatan kode kompiler tidak dapat diandalkan. Penyelarasan, urutan, dan tata letak diserahkan kepada implementasi sehingga kami harus mendukung ABI yang berbeda: http://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit_002dfields-implementation.html

Ya, aku baik-baik saja menghindari yang ini.

Apakah ini berarti bahwa untuk melakukan ini di Servo kita harus menggunakan C shims untuk mendapatkan/mengatur setiap bidang untuk menghindari masalah ini?

Saya baru saja menemukan masalah ini saat membaca tentang Rust. Saya ingin tahu tentang bitfield karena saya melakukan banyak pengembangan kode C/C++ yang disematkan dan kami menggunakan bitfield untuk mengekspresikan status perangkat yang terhubung dengan UART. Statusnya cukup besar tetapi berkat bitfields, itu tidak terlalu buruk. Sangat bersih untuk menandai boolean, bilangan bulat kecil tertentu dan enum sebagai satu hingga beberapa bit karena batasan memori yang rendah. Saya tidak yakin apakah Rust ingin berjalan pada perangkat dengan rentang memori 4KB - 16KB tetapi saya tidak akan menggunakan Rust jika itu mengharuskan saya menggunakan makro untuk mendapatkan bendera bit tunggal. Bitfields memungkinkan kode tingkat yang sangat tinggi di mana makro membuat mengasapi tidak dapat dibaca. Di mana kompatibilitas penyelarasan ABI/spesifik diperlukan, tentu saja makro mungkin menjadi satu-satunya pilihan. Mungkin proyek seperti Servo atau mesin Javascript masa depan di Rust mungkin secara internal menggunakan bitfield untuk menghemat memori dalam kasus tertentu.

@RushPL : Makro karat tidak seperti makro C. Mereka bukan substitusi tekstual, melainkan memanipulasi pohon token melalui pencocokan pola (makro deklaratif) atau kode Rust (makro prosedural). Dalam beberapa kasus, sintaks yang lebih baik dapat disediakan tanpa mereka, tetapi Rust sudah banyak menggunakan makro untuk hal-hal seperti string format yang diperiksa tipe ( std::fmt ).

Yah, itu masih melibatkan pemberian nomor bit tertentu, bukan? (karenanya membuat kode rawan kesalahan)
let some_state = int_from_bits!(object.state, 3, 5) // 5 bit number from bit 3
vs
let some_state = object.some_state // compiler does all the magic as it should be

Nah, satu hal yang dapat Anda lakukan adalah menghasilkan struct dengan metode untuk mengaksesnya. Kerugiannya adalah ketidakmampuan untuk menggunakannya dalam ekspresi konstan karena kurangnya eksekusi fungsi waktu kompilasi Rust.

Hal yang sama dapat Anda lakukan dengan C atau C++ jika tidak menggunakan bitfield tetapi apakah menghasilkan kode merupakan jawaban yang bagus? Seseorang dapat melewati obat generik yang mendukung dan sebagai gantinya menghasilkan semua kode untuk tipe yang berbeda. Bagaimanapun, hanya 2 sen saya dari perspektif seseorang yang peduli dengan ukuran struktur data dan kemudahan penggunaan bidang yang disematkan.

Lihat: RFC: bidang bit dan pencocokan bit
https://github.com/rust-lang/rfcs/pull/29

Apakah makro bitflags! yang baru mengatasi masalah ini?

https://github.com/mozilla/rust/pull/13072

Mungkin bijaksana untuk menutup masalah ini dengan cara apa pun, mengingat respons yang suam-suam kuku dan persyaratan yang tidak jelas.

Masalah ini telah dipindahkan ke repo RFC: rust-lang/rfcs#314

Apakah halaman ini membantu?
0 / 5 - 0 peringkat