# Pre-RFC: anonymous struct and union types

**URL:** https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894
**Category:** language design
**Created:** [August 20, 2016, 10:29pm UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894 "2016-08-20T22:29:16Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)
#### Post date: [August 20, 2016, 10:29pm UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/1 "2016-08-20T22:29:16Z")

</div>

C structure and union types can include anonymous unions or anonymous structs. (The C11 standard allows this, and C compilers have allowed it for decades as an extension.) For instance:

```nohighlight
struct Variant {
    int type;
    union {
        uint64_t u;
        double d;
    };
};

```

Omitting the field names for such a union or struct embeds its fields directly in the containing struct or union, while keeping the struct/union semantics for field layout and overlap. For instance, the structure above allows the following field accesses:

- `v.type`
- `v.u`
- `v.d`

These constructs also nest arbitrarily. An anonymous union allows overlapping fields that won’t get used at the same time. An anonymous struct within a union allows grouping together multiple fields that need to exist simultaneously. For instance, consider adding a counted string to the above structure:

```nohighlight
struct Variant {
    int type;
    union {
        uint64_t u;
        double d;
        struct {
            char *s;
            size_t slen;
        };
    };
};

```

This allows accessing `v.s` and `v.slen`.

Note that you can define an inner struct or union without omitting the field name as well:

```nohighlight
struct Variant {
    int type;
    union {
        uint64_t u;
        double d;
        struct {
            char *ptr;
            size_t len;
        } s;
    };
};

```

This version would instead have `v.s.ptr` and `v.s.len`.

This pattern includes two new constructs that Rust doesn’t have: defining a struct or union type inline inside another, and omitting a field name to make fields part of the parent type.

For a much larger production example, take a look at [`struct kvm_run`](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/kvm.h?h=v4.7#n217) in the Linux KVM API.

This struct-of-unnamed-union-of-structs pattern occurs in many C APIs, so Rust FFIs will need to interface with it.

Rust code could define types compatible with this layout, using unions and structs; however, each union or struct type used in the definition would require a separate definition and name. And worse, when using the resulting aggregate type, each grouping of fields requires a name; for instance, the unnamed union above would require an explicit name and an additional `.union_name.` in field accesses.

(Cc @retep998, who will likely want this for Windows APIs.)

I’d like to propose an RFC defining syntax for this.

First, for defining a struct or union inline, while still naming the field:

```rust
struct S {
    common: u32,
    fieldname: union {
        field1: u64,
        field2: f64,
        inner_struct: struct {
            inner1: SomeType,
            inner2: AnotherType,
        },
    },
}

```

This syntax should parse unambiguously, because `struct {` or `union {` can’t currently appear where the field type would.

This would have the same semantics as defining a new type with no name, and then declaring the corresponding field with that type.

Any `derive` or `repr` declarations for the top-level struct should automatically apply to the nested types as well, so you can `#![derive(Debug),repr(C)]` for `struct S` above.

Note that you can still use that anonymous type via inference; for instance:

```rust
    fn f(s: S) {
        let u = &s.fieldname;
        println!("{}", u.field1);
    }

```

Finally, for defining an unnamed field:

```rust
struct S {
    common: u32,
    union {
        field1: u64,
        field2: f64,
        struct {
            inner1: SomeType,
            inner2: AnotherType,
        },
    },
}

```

This syntax should parse unambiguously, because `struct {` or `union {` can’t currently appear where the field name would.

This definition effectively inlines all the fields within the top-level structure, while retaining the layout and borrow semantics defined by the struct and union. For instance, after borrowing `inner1` you can still borrow `common` and `inner2`, but you can’t borrow `field1` or `field2`.

---

<div class="post-metadata">

### Author: ![aturon](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/aturon/32/3272_2.png) [@aturon](https://internals.rust-lang.org/u/aturon)
#### Post date: [August 20, 2016, 11:04pm UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/2 "2016-08-20T23:04:19Z")

</div>

From a quick glance, it seems that this proposal includes anonymous structs/unions only within struct/union definitions, but _not_ as types in general. Is there a deep reason for that? All things being equal, it seems nicer to expand the type grammar, such that this isn’t a special case within type definitions but instead just another kind of type. A [closely-related pre-RFC](https://internals.rust-lang.org/t/pre-rfc-unnamed-struct-types/3872) seems to be doing just that.

(I haven’t thought deeply about the implications of any of this, but just wanted to note the general principle of not special-casing the type grammar.)

---

<div class="post-metadata">

### Author: ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)
#### Post date: [August 20, 2016, 11:13pm UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/3 "2016-08-20T23:13:42Z")

</div>

No particular reason. It seems quite reasonable to me to allow anonymous types anywhere a type can appear.

(That proposal could support part of this, as long as the approaches involving sorting fields to unify types don’t get included, or at least not when declared with `repr(C)`.)

However, I don’t want to propose allowing unnamed fields everywhere, only within a struct or union. (And _possibly_ also within an enum variant that uses named fields, for symmetry.)

---

<div class="post-metadata">

### Author: ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)
#### Post date: [August 21, 2016, 1:41am UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/4 "2016-08-21T01:41:46Z")

</div>

> [@josh](#):
>
> No particular reason. **It seems quite reasonable to me to allow anonymous types anywhere a type can appear.**
> 
> (That proposal could support part of this, as long as the approaches involving sorting fields to unify types don't get included, or at least not when declared with repr(C).)
> 
> **However, I don't want to propose allowing unnamed fields everywhere, only within a struct or union.** (And possibly also within an enum variant that uses named fields, for symmetry.)

In the juxtoposition of the two emphasized sentences, it seems like you're drawing a distinction between "anonymous types" and "unnamed fields," but I think they refer to the same idea (which I think is better referred to as "unlabled types," since "anonymous types" is usually used for things like the type of closures). What is the distinction?

---

<div class="post-metadata">

### Author: ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)
#### Post date: [August 21, 2016, 2:22am UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/5 "2016-08-21T02:22:31Z")

</div>

“anonymous struct” or “anonymous union” refers to something like `struct { ... }` or `union { ... }` without a type name, used directly as a type. “unnamed field” refers to a field within an outer struct or union, that has struct or union type itself, and has no field name.

The following uses an anonymous union but not an unnamed field:

```rust
struct S {
    a: T1,
    u: union { b: T2, c: T3 },
}

```

The following uses an anonymous union as an unnamed field:

```rust
struct S {
    a: T1,
    union { b: T2, c: T3 },
}

```

The term “unnamed field” comes from [the GCC documentation](https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html).

---

<div class="post-metadata">

### Author: ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)
#### Post date: [August 21, 2016, 2:42am UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/6 "2016-08-21T02:42:51Z")

</div>

I missed the unnamed field aspect of the RFC. This doesn’t seem to impact layout, is the goal just to have the API mirror C’s representation? It seems to me like a feature that would be perplexing.

---

<div class="post-metadata">

### Author: ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)
#### Post date: [August 21, 2016, 4:12am UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/7 "2016-08-21T04:12:27Z")

</div>

> [@withoutboats](#):
>
> I missed the unnamed field aspect of the RFC. This doesn't seem to impact layout, is the goal just to have the API mirror C's representation?

Yes, as well as C's expressive power for layout, for several reasons:

- I'd like to avoid having to invent names for elements that the C API doesn't have names for.
- I'd like to avoid forcing every caller to use those names rather than using the fields directly as they would in C.
- I'd like to avoid mass refactoring of a codebase when moving fields around.

Without this, when someone looks at the C API and its documentation, and wants to construct corresponding Rust code, they have to remember and add the invented union name.

In addition, this syntax with `struct { ... }` and `union { ... }` gives a large amount of expressive power over structure layout. If you're used to reading unnamed unions and structs, you can very quickly translate between a memory representation and a structure layout, while keeping that separate from semantic grouping of fields. `union { ... }` acts like `|` in an ADT, and `struct { ... }` acts like a grouping operator to put multiple fields in one branch of the `|`.

---

<div class="post-metadata">

### Author: ![petrochenkov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/petrochenkov/32/2784_2.png) [@petrochenkov](https://internals.rust-lang.org/u/petrochenkov)
#### Post date: [August 21, 2016, 10:09am UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/8 "2016-08-21T10:09:35Z")

</div>

I’d be in favor of “unnamed fields”, but mildly against named fields with unnamed types, because they are two pretty different things.

* * *

Named fields with unnamed types are merely a convenience, any such type can be easily outlined.

```rust
struct S {
    a: u8,
    b: struct {
        c: u8,
    }
}

=>

struct S_B {
    c: u8,
}

struct S {
    a: u8,
    b: C_B,
}

```

Such outlining is 1) only two tokens longer 2) doesn’t affect interface of `S` and therefore invisible for users - the field `c` is accessed as `b.c` in both cases. I’d argue that if `struct { FIELDS.... }` is allowed in field type position, then it should be allowed in any type position, e.g.

```rust
fn f() -> struct { key: u8, value: u8 } { .... }

```

and I don’t think this is a sugar that Rust urgently needs.

* * *

“Unnamed fields” with “unnamed types” as they are used in C don’t even need to be types or fields, they are _layout specifiers_ and in theory can use any syntax not reminding `struct`/`union` declarations. Such modifiers give ability to build an arbitrary complex layout for an aggregate `S` while keeping it’s interface as simple as a struct with a set of fields:

```rust
// I intentionally use the non-`struct {....}` syntax to highlight the difference from named fields with unnamed types.
struct S {
    product [
        a: u8,
        b: u16,
        sum [
            c: u32,
            d: u64,
        ]
        product [
            e: i8,
            f: i16,
        ]
    ]
    sum [
        g: i32,
        h: i64,
    ]
}

<=>

custom_aggregate S {
    a: u8,
    b: u16,
    c: u32,
    d: u64,
    e: i8,
    f: i16,
    g: i32,
    h: i64,
}

```

This is certainly a feature which gives new abilities (as opposed to just convenience) by affecting user-visible interfaces . Note that this is still a fringe low level feature that is useful in quite specific situations. One problem with this is that unions currently require unsafe blocks on any access to fields, so you can’t do some things from C, for example the [field alias trick](https://github.com/rust-lang/rfcs/pull/1546#issuecomment-200757495) as conveniently as in C. However, I think the rules can be relaxed a bit to allow safe access to [common initial sequences](http://en.cppreference.com/w/cpp/language/data_members#Standard_layout), safe writes to trivially destructible fields and maybe something else.

---

<div class="post-metadata">

### Author: ![petrochenkov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/petrochenkov/32/2784_2.png) [@petrochenkov](https://internals.rust-lang.org/u/petrochenkov)
#### Post date: [August 21, 2016, 10:25am UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/9 "2016-08-21T10:25:31Z")

</div>

It would also be nice to incorporate `enum`s into the picture, i.e. give “custom aggregates” ability to include tagged unions in their layout as well.

```rust
struct S {
    span: Span,
    id: Id,
    enum {
        Foo(u8),
        Bar(u16),
    }
    enum { // Fun: `S` has two discriminants
        A,
        B,
    }
    union {
        a: u8,
        b: u16,
    }
}

```

---

<div class="post-metadata">

### Author: ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)
#### Post date: [August 21, 2016, 10:56am UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/10 "2016-08-21T10:56:18Z")

</div>

Named fields with unnamed types, while not significantly longer in tokens, have a semantic overhead in that you can’t see the layout of the inner struct/union inline in the outer struct/union.

However, if the consensus rejects that, I can imagine implementing them with a sufficiently powerful macro system, by desugaring them to a separate type. Given that, I would put a higher priority on unnamed fields.

Creating a new set of layout primitives (and pseudo-keywords) seems excessive, when the layout they implement effectively works like struct or union. Using a different syntax seems fine if it provides more expressive power, though.

---

<div class="post-metadata">

### Author: ![petrochenkov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/petrochenkov/32/2784_2.png) [@petrochenkov](https://internals.rust-lang.org/u/petrochenkov)
#### Post date: [August 21, 2016, 11:24am UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/11 "2016-08-21T11:24:22Z")

</div>

> [@josh](#):
>
> you can't see the layout of the inner struct/union inline in the outer struct/union

This is not a problem unique to C FFI though, literally any struct with fields having non-builtin types has it.

```rust
struct S {
    a: Type, // I have to go somewhere and find out what `Type` is :(
}

```

IDEs usually have features a la "show pop-up window with `Type`'s definition on mouse-over", Eclipse certainly has it and IIRC Visual Studio and QtCreator had this ability too. Now the only thing we need is IDEs supporting this for Rust... but I haven't actually checked recently, maybe it's already available somewhere?

> [@josh](#):
>
> Creating a new set of layout primitives (and pseudo-keywords) seems excessive

I used pseudo-keywords for explanatory purpose to show that these "unions" and "structs" don't necessarily have to exist at type level, the original syntax `struct { FIELDS.... }`/`union { FIELDS.... }` seems good and sufficient.

---

<div class="post-metadata">

### Author: ![strega-nil](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/strega-nil/32/13228_2.png) [@strega-nil](https://internals.rust-lang.org/u/strega-nil)
#### Post date: [August 21, 2016, 4:00pm UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/12 "2016-08-21T16:00:30Z")

</div>

> This is not a problem unique to C FFI though, literally any struct with fields having non-builtin types has it.

Usually when you're doing this, tho, they're intended to be a part of the same whole. It's not like

```rust
struct Doop {
    v: Vec<u8>,
}

```

which just has an opaque wrapper, as opposed to

```rust
struct string {
    length: usize,
    union {
        short: [u8; 16],
        long: struct {
            cap: usize,
            ptr: *const u8,
        }
    }
}

```

---

<div class="post-metadata">

### Author: ![nrc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nrc/32/126_2.png) [@nrc](https://internals.rust-lang.org/u/nrc)
#### Post date: [August 21, 2016, 9:38pm UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/13 "2016-08-21T21:38:04Z")

</div>

> [@josh](#):
>
> This struct-of-unnamed-union-of-structs pattern occurs in many C APIs, so Rust FFIs will need to interface with it.
> 
> Rust code could define types compatible with this layout, using unions and structs; however, each union or struct type used in the definition would require a separate definition and name. And worse, when using the resulting aggregate type, each grouping of fields requires a name; for instance, the unnamed union above would require an explicit name and an additional .union\_name. in field accesses.

This seems key - how often does this pattern occur in practice in C codebases and how often are Rust programmers likely to encounter it? I do think that, in isolation, allowing un-named fields is a mis-feature - it seems to make data structures more confusing, rather than more ergonomic - all it seems to save is a field access - `.field`, which is not a lot of typing (c.f., anon structs, which have applicability for named args, etc.). So, this seems like it would make the language worse to me, but might be justified if it solves _a lot_ of pain when doing FFI

---

<div class="post-metadata">

### Author: ![retep998](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/retep998/32/729_2.png) [@retep998](https://internals.rust-lang.org/u/retep998)
#### Post date: [August 21, 2016, 10:59pm UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/14 "2016-08-21T22:59:45Z")

</div>

> [@nrc](#):
>
> how often does this pattern occur in practice in C codebases and how often are Rust programmers likely to encounter it?

364 mentions of `DUMMYUNIONNAME` in Windows API and 171 mentions of `DUMMESTRUCTNAME`, which is used in most cases of unnamed structs/unions inside other structs/unions.

---

<div class="post-metadata">

### Author: ![comex](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/comex/32/2587_2.png) [@comex](https://internals.rust-lang.org/u/comex)
#### Post date: [August 22, 2016, 1:41am UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/15 "2016-08-22T01:41:17Z")

</div>

Unix kernel headers often fake this with #defines (for portability), like the following from Linux:

```rust
#define sa_handler	_u._sa_handler
#define sa_sigaction	_u._sa_sigaction

```

paired with this struct definition:

```rust
struct sigaction {
    union {
      __sighandler_t _sa_handler;
      void (*_sa_sigaction)(int, struct siginfo *, void *);
    } _u;
    (..other fields..)
};

```

You’re supposed to write `foo->sa_handler` rather than interacting with the `_u` and `_sa_handler` fields directly - indeed, the former name is standardized while the latter is meant to be an implementation detail. Ideally Rust bindings for such APIs would be written as true anonymous structs (though getting bindgen to do it automatically would not be easy).

There are quite a lot of these - here’s a grep of /usr/include from OS X:

[http://pastie.org/10938609](http://pastie.org/10938609)

and here’s the Linux kernel:

[http://pastie.org/10938610](http://pastie.org/10938610)

---

<div class="post-metadata">

### Author: ![ktakeda](https://avatars.discourse-cdn.com/v4/letter/k/b2d939/32.png) [@ktakeda](https://internals.rust-lang.org/u/ktakeda)
#### Post date: [August 27, 2016, 7:43am UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/16 "2016-08-27T07:43:39Z")

</div>

Using Deref, unnamed field can be realized as follows:

```
use std::ops::Deref;

struct InnerS {
    inner_a: i32,
    inner_b: i32
}

struct S {
    a: u32,
    inner: InnerS
}

impl Deref for S {
    type Target = InnerS;

    fn deref(&self) -> &InnerS {
        &self.inner
    }
}

fn main() {
    let x = S {a: 1, inner: InnerS {inner_a: 2, inner_b: 3}};
    println!("inner_a = {}", x.inner_a);
    // -> "inner_a = 2"
}

```

It seems sufficient for omitting field names. 🙂

---

<div class="post-metadata">

### Author: ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)
#### Post date: [August 27, 2016, 5:06pm UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/17 "2016-08-27T17:06:20Z")

</div>

You can only have one implementation of Deref for a type, so that would only allow one unnamed field per type, and only if the type didn’t need to use Deref for anything else.

---

<div class="post-metadata">

### Author: ![nrc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nrc/32/126_2.png) [@nrc](https://internals.rust-lang.org/u/nrc)
#### Post date: [August 28, 2016, 6:53am UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/18 "2016-08-28T06:53:43Z")

</div>

I would strongly recommend against this - Deref is designed for implementing smart pointers and this (mis-)use is confusing at best. See [https://github.com/nrc/patterns/blob/master/anti\_patterns/deref.md](https://github.com/nrc/patterns/blob/master/anti_patterns/deref.md) for more details.

---

<div class="post-metadata">

### Author: ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)
#### Post date: [September 1, 2016, 11:17pm UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/19 "2016-09-01T23:17:32Z")

</div>

Agreed; Deref doesn’t make sense for this.

---

<div class="post-metadata">

### Author: ![zackw](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/zackw/32/2071_2.png) [@zackw](https://internals.rust-lang.org/u/zackw)
#### Post date: [January 20, 2017, 12:07am UTC](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894/20 "2017-01-20T00:07:56Z")

</div>

Can we dust this off? I was about to tackle adding full support for `siginfo_t` to the libc crate (which is needed in order for `waitid` to be useful; right now many platforms don’t expose the `si_pid` and `si_status` fields) but the problem is that both Linux and NetBSD do the thing @comex described, where there’s a bunch of implementation-detail substructures hidden from the public C API with macros. The [_documented_ `siginfo_t`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html) looks something like

```rust
typedef struct {
    int si_signo;
    int si_code;
    int si_errno;
    pid_t si_pid;
    uid_t si_uid;
    void *si_addr;
    int si_status;
    long si_band;
    union sigval si_value;
} siginfo_t;

```

But the [actual NetBSD definition](http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/sys/siginfo.h?rev=1.30&content-type=text/x-cvsweb-markup&only_with_tag=MAIN) looks like this:

```rust
struct _ksiginfo {
	int	_signo;
	int	_code;
	int	_errno;
#ifdef _LP64
	/* In _LP64 the union starts on an 8-byte boundary. */
	int	_pad;
#endif
	union {
		struct {
			pid_t	_pid;
			uid_t	_uid;
			sigval_t	_value;
		} _rt;

		struct {
			pid_t	_pid;
			uid_t	_uid;
			int	_status;
			clock_t	_utime;
			clock_t	_stime;
		} _child;

		struct {
			void *_addr;
			int	_trap;
			int	_trap2;
			int	_trap3;
		} _fault;

		struct {
			long	_band;
			int	_fd;
		} _poll;
	} _reason;
};
/* ... */
typedef union siginfo {
	char	si_pad[128];	/* Total size; for future expansion */
	struct _ksiginfo _info;
} siginfo_t;

/** Field access macros */
#define	si_signo	_info._signo
#define	si_code _info._code
#define	si_errno	_info._errno

#define	si_value	_info._reason._rt._value
#define	si_pid _info._reason._child._pid
#define	si_uid _info._reason._child._uid
#define	si_status	_info._reason._child._status
#define	si_utime	_info._reason._child._utime
#define	si_stime	_info._reason._child._stime
/* etc */

```

Contrast the [FreeBSD definition](https://github.com/freebsd/freebsd/blob/master/sys/sys/signal.h#L216), which still has the union, but far fewer of the fields are inside. C programmers don’t have to care (except that they’ll be in for a nasty surprise if they try to use the `si_*` identifiers for anything else).

Not only would it be nice if the libc crate could be equally convenient, at this point we may not be _able_ to adopt any of the workarounds (e.g. accessor methods) for `siginfo_t` without breaking compatibility.

[Next page](https://internals.rust-lang.org/t/pre-rfc-anonymous-struct-and-union-types/3894.md?page=2)
