You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: book/src/using-unions.md
+36-30
Original file line number
Diff line number
Diff line change
@@ -1,10 +1,14 @@
1
1
# Using the Union Types Generated by Bindgen
2
2
3
-
**NOTE:** As of Rust version 1.17, Rust does not have a stable `union` type. Issue [#32836](https://github.com/rust-lang/rust/issues/32836) tracks the stabilization of a `union` type in Rust.
3
+
**NOTE**: Rust 1.19 stabilized the `union` type (see Rust issue [#32836](https://github.com/rust-lang/rust/issues/32836)).
4
4
5
-
By using the flag `--unstable-rust`, bindgen will generate the preliminary unstable `union` type.
5
+
You can pass the `--rust-target` option to tell `bindgen` to target a specific version of Rust.
6
+
By default, `bindgen` will target the latest stable Rust.
7
+
The `--rust-target` option accepts a specific stable version (such as "1.0" or "1.19") or "nightly".
6
8
7
-
In general, most interactions with unions (either reading or writing) are unsafe.
9
+
**NOTE**: The `--unstable-rust` option is deprecated; use `--rust-target nightly` instead.
10
+
11
+
In general, most interactions with unions (either reading or writing) are unsafe, meaning you must surround union accesses in an `unsafe {}` block.
8
12
9
13
For this discussion, we will use the following C type definitions:
With `struct`s generated by bindgen from C, it is possible to initialize fields in a "normal" rust way:
48
+
Bindgen can emit one of two Rust types that correspond to C unions:
45
49
46
-
```rust,ignore
47
-
mod bindings;
50
+
* Rust's `union` builtin (only available in Rust >= 1.19, including nightly)
51
+
* Bindgen's `BindgenUnion` (available for all Rust targets)
48
52
49
-
fn main() {
50
-
let x = bindings::alpha_t {
51
-
a: 1,
52
-
b: -1,
53
-
};
54
-
}
55
-
```
53
+
Bindgen uses the following logic to determine which Rust union type to emit:
54
+
55
+
* If the Rust target is >= 1.19 (including nightly) AND each field of the union can derive `Copy`, then generate a `union` builtin.
56
+
* Otherwise, generate a `BindgenUnion`.
57
+
58
+
## Using the `union` builtin
59
+
60
+
When using the `union` builtin type, there are two choices for initialization:
56
61
57
-
When using the unstable `union` type, there are two choices for initialization: Zeroed, and with a specific variant.
62
+
1. Zero
63
+
2. With a specific variant
58
64
59
65
```rust,ignore
60
-
#![feature(untagged_unions)]
61
-
mod bindings_unstable;
66
+
mod bindings_builtin_union;
62
67
63
-
fn unstable() {
68
+
fn union_builtin() {
64
69
// Initalize the union to zero
65
-
let x = bindings_unstable::greek_t::default();
70
+
let x = bindings_builtin_union::greek_t::default();
66
71
67
72
// If `--with-derive-default` option is not used, the following may be used
68
73
// to initalize the union to zero:
69
-
let x = unsafe{ std::mem::zeroed::<bindings_unstable::greek_t>() };
74
+
let x = unsafe{ std::mem::zeroed::<bindings_builtin_union::greek_t>() };
70
75
71
76
// Or, it is possible to initialize exactly one variant of the enum:
72
-
let x = bindings_unstable::greek_t {
73
-
alfa: bindings_unstable::alpha_t {
77
+
let x = bindings_builtin_union::greek_t {
78
+
alfa: bindings_builtin_union::alpha_t {
74
79
a: 1,
75
80
b: -1,
76
81
},
@@ -83,16 +88,17 @@ fn unstable() {
83
88
}
84
89
```
85
90
86
-
## Using the stable BindgenUnion types
91
+
## Using the `BindgenUnion` type
87
92
88
-
For versions of Rust that do not support the new `union` type, bindgen will generate types which provide union-like access to structure fields.
93
+
If the target Rust version does not support the new `union` type or there is a field that cannot derive `Copy`, then bindgen will provide union-like access to a `struct`.
89
94
90
-
Interacting with these unions is slightly different than the new `union` types. Whenever a variant of the union is accessed, it must be done through a reference.
95
+
Interacting with these unions is slightly different than the new `union` types.
96
+
You must access union variants through a reference.
91
97
92
98
```rust,ignore
93
99
mod bindings;
94
100
95
-
fn stable() {
101
+
fn bindgenunion() {
96
102
// `default()` or `zeroed()` may still be used with Bindgen's Union types
97
103
let mut x = bindings::greek_t::default();
98
104
@@ -116,7 +122,7 @@ fn stable() {
116
122
}
117
123
```
118
124
119
-
If you attempt to access a BindgenUnion field directly, you will see errors like this:
125
+
If you attempt to access a `BindgenUnion` field directly, you will see errors like this:
0 commit comments