Skip to content

Commit 13f2b9a

Browse files
author
bors-servo
authored
Auto merge of #1052 - ambaxter:bitfield_docs, r=fitzgen
Added mdbook entry for bitfields. Fixes #818
2 parents 2b81788 + b969bfb commit 13f2b9a

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

book/src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@
1919
- [Preventing the Derivation of `Copy` and `Clone`](./nocopy.md)
2020
- [Generating Bindings to C++](./cpp.md)
2121
- [Using Unions](./using-unions.md)
22+
- [Using Bitfields](./using-bitfields.md)
2223
- [FAQ](./faq.md)

book/src/using-bitfields.md

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Using the Bitfield Types Generated by Bindgen
2+
3+
## Bitfield Strategy Overview
4+
5+
As Rust does not support bitfields, Bindgen generates a struct for each with the following characteristics
6+
* Immutable getter functions for each bitfield named ```<bitfield>```
7+
* Setter functions for each contiguous block of bitfields named ```set_<bitfield>```
8+
* Far each contiguous block of bitfields, Bindgen emits an opaque physical field that contains one or more logical bitfields
9+
* A static constructor ```new_bitfield_{1, 2, ...}``` with a parameter for each bitfield contained within the opaque physical field.
10+
11+
## Bitfield examples
12+
13+
For this discussion, we will use the following C type definitions and functions.
14+
```c
15+
typedef struct {
16+
unsigned int a: 1;
17+
unsigned int b: 1;
18+
unsigned int c: 2;
19+
20+
} StructWithBitfields;
21+
22+
// Create a default bitfield
23+
StructWithBitfields create_bitfield();
24+
25+
// Print a bitfield
26+
void print_bitfield(StructWithBitfields bfield);
27+
```
28+
29+
Bindgen creates a set of field getters and setters for interacting with the bitset. For example,
30+
31+
```rust,ignore
32+
let mut bfield = unsafe { create_bitfield() };
33+
34+
bfield.set_a(1);
35+
println!("a set to {}", bfield.a());
36+
bfield.set_b(1);
37+
println!("b set to {}", bfield.b());
38+
bfield.set_c(3);
39+
println!("c set to {}", bfield.c());
40+
41+
unsafe { print_bitfield(bfield) };
42+
```
43+
44+
will print out
45+
46+
```text
47+
a set to 1
48+
b set to 1
49+
c set to 3
50+
StructWithBitfields: a:1, b:1, c:3
51+
```
52+
53+
Overflowing a bitfield will result in the same behavior as in C/C++: the bitfield will be set to 0.
54+
55+
```rust,ignore
56+
let mut bfield = unsafe { create_bitfield() };
57+
bfield.set_a(1);
58+
bfield.set_b(1);
59+
bfield.set_c(12);
60+
println!("c set to {} due to overflow", bfield.c());
61+
62+
unsafe { print_bitfield(bfield) };
63+
```
64+
65+
will print out
66+
67+
```text
68+
c set to 0 due to overflow
69+
StructWithBitfields: a:1, b:1, c:0
70+
```
71+
72+
To create a new bitfield in Rust, use the bitfield allocation unit constructor.
73+
74+
Note: This requires the Builder's derive_default to be set to true, otherwise the necessary Default functions won't be generated.
75+
76+
```rust,ignore
77+
let bfield = StructWithBitfields{
78+
_bitfield_1: StructWithBitfields::new_bitfield_1(0,0,0),
79+
..Default::default()
80+
};
81+
82+
unsafe { print_bitfield(bfield) };
83+
```
84+
85+
This will print out
86+
87+
```text
88+
StructWithBitfields: a:1, b:0, c:2
89+
```

0 commit comments

Comments
 (0)