Skip to content

Added mdbook entry for bitfields. #1052

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 17, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@
- [Preventing the Derivation of `Copy` and `Clone`](./nocopy.md)
- [Generating Bindings to C++](./cpp.md)
- [Using Unions](./using-unions.md)
- [Using Bitfields](./using-bitfields.md)
- [FAQ](./faq.md)
89 changes: 89 additions & 0 deletions book/src/using-bitfields.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Using the Bitfield Types Generated by Bindgen

## Bitfield Strategy Overview

As Rust does not support bitfields, Bindgen generates a struct for each with the following characteristics
* Immutable getter functions for each bitfield named ```<bitfield>```
* Setter functions for each contiguous bsock of bitfields named ```set_<bitfield>```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"bsock" -> "block"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

* Far each contiguous block of bitfields, Bindgen emits an opaque physical field that contains one or more logical bitfields
* A static constructor ```new_bitfield_{1, 2, ...}``` with a parameter for each bitfield contained within the opaque physical field.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: s/for each bitfield/for each contiguous block of bitfields/

There is a constructor for each of those physical, opaque fields that we end up generating, which is roughly equivalent to sets of contiguous bitfields.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


## Bitfield examples
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome 👍


For this discussion, we will use the following C type definitions and functions.
```c
typedef struct {
unsigned int a: 1;
unsigned int b: 1;
unsigned int c: 2;

} StructWithBitfields;

// Create a default bitfield
StructWithBitfields create_bitfield();

// Print a bitfield
void print_bitfield(StructWithBitfields bfield);
```

Bindgen creates a set of field getters and setters for interacting with the bitset. For example,

```rust,ignore
let mut bfield = unsafe { create_bitfield() };

bfield.set_a(1);
println!("a set to {}", bfield.a());
bfield.set_b(1);
println!("b set to {}", bfield.b());
bfield.set_c(3);
println!("c set to {}", bfield.c());

unsafe { print_bitfield(bfield) };
```

will print out

```text
a set to 1
b set to 1
c set to 3
StructWithBitfields: a:1, b:1, c:3
```

Overflowing a bitfield will result in the same behavior as in C/C++: the bitfield will be set to 0.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it just happen to set to 0 in this case or is that really what the standard says should happen? My reading of the C++ standard doesn't come up with anything either way. Same with the C11 standard.

I think we should leave overflow unspecified as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my googling Stackoverflow that's what the standard says: https://stackoverflow.com/questions/4908300/overflow-in-bit-fields#4908606

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!


```rust,ignore
let mut bfield = unsafe { create_bitfield() };
bfield.set_a(1);
bfield.set_b(1);
bfield.set_c(12);
println!("c set to {} due to overflow", bfield.c());

unsafe { print_bitfield(bfield) };
```

will print out

```text
c set to 0 due to overflow
StructWithBitfields: a:1, b:1, c:0
```

To create a new bitfield in Rust, use the bitfield allocation unit constructor.

Note: This requires the Builder's derive_default to be set to true, otherwise the necessary Default functions won't be generated.

```rust,ignore
let bfield = StructWithBitfields{
_bitfield_1: StructWithBitfields::new_bitfield_1(0,0,0),
..Default::default()
};

unsafe { print_bitfield(bfield) };
```

This will print out

```text
StructWithBitfields: a:1, b:0, c:2
```