Stream: t-lang/wg-unsafe-code-guidelines

Topic: repr(C) unions need padding


gnzlbg (Jun 30 2019 at 08:22, on Zulip):

This union needs to have padding:

#[repr(C)] struct S(u8, u32);
#[repr(C)] union U { s: S };

When doing a roundtrip from Rust->C->Rust, the content of the padding won't be preserved.

gnzlbg (Jun 30 2019 at 08:23, on Zulip):

The "bag of bits" definition is fine, in that one can read and write all bits of the union. But if the bit is a padding bit, reading it returns undef.

RalfJ (Jun 30 2019 at 09:17, on Zulip):

so that's a thing in C as well?

RalfJ (Jun 30 2019 at 09:18, on Zulip):

dang :(

gnzlbg (Jun 30 2019 at 09:46, on Zulip):

@ralf no, i was wrong

gnzlbg (Jun 30 2019 at 09:46, on Zulip):

@RalfJ

gnzlbg (Jun 30 2019 at 09:47, on Zulip):

I've posted in the issue

gnzlbg (Jun 30 2019 at 09:47, on Zulip):

our repr(C) union implementation has a bug if it doesn't preserve the contents of field padding

RalfJ (Jun 30 2019 at 10:02, on Zulip):

aha? so C does preserve it?

gnzlbg (Jun 30 2019 at 10:08, on Zulip):

no, C does not preserve it

gnzlbg (Jun 30 2019 at 10:08, on Zulip):

C unions might only have trailing padding, and that trailing padding does not need to be preserved

gnzlbg (Jun 30 2019 at 10:09, on Zulip):

If a union does not have trailing padding, then it has no padding - but union fields can have padding

gnzlbg (Jun 30 2019 at 10:09, on Zulip):

Does that make sense?

RalfJ (Jun 30 2019 at 10:50, on Zulip):

but it cant know which field it is, in general? I thought C unions are "extensible"

RalfJ (Jun 30 2019 at 10:51, on Zulip):

as in, if one side has fewer fields than the other, data can still be forwarded correctly

RalfJ (Jun 30 2019 at 10:51, on Zulip):

(that's AFAIK something that libraries use to remain forward compatible)

Last update: Nov 19 2019 at 18:30UTC