Skip to content

Commit

Permalink
Document the alignment procedure for UNION2!
Browse files Browse the repository at this point in the history
  • Loading branch information
Susurrus committed Jun 3, 2017
1 parent 4c58c31 commit 11650a1
Showing 1 changed file with 35 additions and 1 deletion.
36 changes: 35 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,11 @@ pub type PGROUP_AFFINITY = *mut GROUP_AFFINITY;
## Unions

* `UNION!` is being deprecated in favor of `UNION2!` in order to more closely align with the new
untagged union feature.
untagged union feature. Note that the `UNION2` macro requires the alignment of the struct to
be specified via the datatype of the backing data array. Additionally this alignment can vary
for 32- and 64-bit builds and needs to be specified for both if they're different.

Example C union:
```C
typedef union {
USN_RECORD_COMMON_HEADER Header;
Expand All @@ -133,6 +136,9 @@ typedef union {
USN_RECORD_V4 V4;
} USN_RECORD_UNION, *PUSN_RECORD_UNION;
```

For unions where the alignment matches for 32- and 64-bits the alignment can just be specified
once:
```Rust
UNION2!{union USN_RECORD_UNION {
[u64; 10],
Expand All @@ -144,6 +150,34 @@ UNION2!{union USN_RECORD_UNION {
pub type PUSN_RECORD_UNION = *mut USN_RECORD_UNION;
```

Otherwise the alignment needs to specified first for the 32-bit and then the 64-bit builds like:
```Rust
UNION2!{union USN_RECORD_UNION {
[u32; 20] [u64; 10],
Header Header_mut: USN_RECORD_COMMON_HEADER,
V2 V2_mut: USN_RECORD_V2,
V3 V3_mut: USN_RECORD_V3,
V4 V4_mut: USN_RECORD_V4,
}}
pub type PUSN_RECORD_UNION = *mut USN_RECORD_UNION;
```

To determine the alignment compile and run a C++ program on Windows specifying `x` as having the
datatype that's being tested using the following code to print out the necessary array declaration
for the `UNION2` macro:
```C++
char const * type_for_alignment(uintptr_t align) {
switch (align) {
case 1: return "u8";
case 2: return "u16";
case 4: return "u32";
case 8: return "u64";
}
throw;
}
#define PRINT_UNION(x) cout << "[" << type_for_alignment(alignof(x)) << "; " << sizeof(x) / alignof(x) << "]" << endl;
```
## Anonymous unions and structs
* If the type `FOO` contains a single anonymous struct or union, give the anonymous struct or
Expand Down

0 comments on commit 11650a1

Please sign in to comment.