Rust: support bit fields for C interop

Created on 22 Aug 2013  ·  14Comments  ·  Source: rust-lang/rust

Some C APIs have structs that use bitfields, and these are rather cumbersome to use from rust right now. Perhaps we should have some kind of support for this, or at least a macro that takes care of it.

This has come up specifically with Azure used in Servo.

Most helpful comment

I just stumbled upon this issue while reading about Rust. I was curious about bitfields because I do a lot of embedded C/C++ code development and we use bitfields for expressing a UART connected device's state. The state is quite big but thanks to bitfields it is not too bad. It is very clean to mark the booleans, certain small integers and enums as single to few bits due to low memory constraints. I am not sure if Rust aspires to run on a device with 4KB - 16KB memory range but I would not use Rust if it required me to use macros to get single bit flags. Bitfields allow very high level code where macros make unreadable bloat. Where ABI/specific alignment compatibility is needed of course macros might be the only choice. Perhaps projects like Servo or otherwise future Javascript engines in Rust might internally use bitfields to save memory in specific cases.

All 14 comments

Seems inevitable. I'd prefer trying the macro route first.

It does not seem inevitable to me... I feel like we can get by just fine using uints and explicit masking. Some macros for supporting bitsets would be fine of course. I suspect that the layout of bitfields is done entirely in clang, not LLVM, though I could be wrong, which would make this quite a pain for us to support.

To be fair though, I never understood the appeal of bitfields even in C. It always seemed like it was handing over control over layout and masking and all the rest to the compiler, but you only use them when you care a lot about the details -- precisely when I'd rather know exactly what's going on.

The Linux kernel (and many libraries) avoid bitfields in general, because the compiler's code generation is unreliable. The alignment, order and layout are are left up to the implementation so we would have to support different ABIs: http://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit_002dfields-implementation.html

Yeah, I'm ok avoiding this one.

Does this mean that to do this in Servo we have to use C shims to get/set each field in order to avoid these issues?

I just stumbled upon this issue while reading about Rust. I was curious about bitfields because I do a lot of embedded C/C++ code development and we use bitfields for expressing a UART connected device's state. The state is quite big but thanks to bitfields it is not too bad. It is very clean to mark the booleans, certain small integers and enums as single to few bits due to low memory constraints. I am not sure if Rust aspires to run on a device with 4KB - 16KB memory range but I would not use Rust if it required me to use macros to get single bit flags. Bitfields allow very high level code where macros make unreadable bloat. Where ABI/specific alignment compatibility is needed of course macros might be the only choice. Perhaps projects like Servo or otherwise future Javascript engines in Rust might internally use bitfields to save memory in specific cases.

@RushPL: Rust macros are not like C macros. They're not a textual substitution, but rather manipulate token trees via either pattern matching (declarative macros) or Rust code (procedural macros). In some cases better syntax can be provided without them, but Rust already makes heavy use of macros for stuff like type-checked format strings (std::fmt).

Well, it would still involve providing specific bit numbers, right? (hence making the code error prone)
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

Well, one thing you could do is generate a struct with methods for accessing it. The loss is the inability to use it in constant expressions due to Rust's lack of compile-time function execution.

Same thing you can do with C or C++ if not using bitfields but is generating code a good answer? One could skip supporting generics and instead generate all the code for different types. Anyway, just my 2 cents from a perspective of someone who cares about size of data structures and ease of use of embedded fields.

See: RFC: bit fields and bit matching
https://github.com/rust-lang/rfcs/pull/29

Does the new bitflags! macro address this issue?

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

It might be prudent to close this issue either way, given the lukewarm response and vague requirements.

This issue has been moved to the RFCs repo: rust-lang/rfcs#314

Was this page helpful?
0 / 5 - 0 ratings