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

Topic: Unions with padding


gnzlbg (Jul 01 2019 at 18:20, on Zulip):

@RalfJ why are you so concerned about giving #[repr(transparent)] unions padding?

gnzlbg (Jul 01 2019 at 18:21, on Zulip):

AFAICT, writing and reading to the padding would be ok - the expectation that the padding does not to change on, e.g., move/copy/etc. would be incorrect under that model, but I don't follow why that is a big deal

RalfJ (Jul 01 2019 at 18:22, on Zulip):

I was just saying that in case it turns out that we have vectors with padding at the end one day or so

RalfJ (Jul 01 2019 at 18:22, on Zulip):

we could still have both a "bags of bits" semantics and a vector ABI for unions, as long as the bag of bits is just the part "covered" by any union fields

gnzlbg (Jul 01 2019 at 18:22, on Zulip):

Yeah, that's also a case, but I meant also in the middle, e.g., #[repr(transparent)] union U { x: (u8, u32) }having 3 padding bytes between the u8 and the u32 that are not preserved on move / copy / etc.

RalfJ (Jul 01 2019 at 18:23, on Zulip):

or maybe we just allow uninitalized integers, and then there's no need to use MaybeUninit for vector types :P

RalfJ (Jul 01 2019 at 18:23, on Zulip):

Yeah, that's also a case, but I meant also in the middle, e.g., #[repr(transparent)] union U { x: (u8, u32) }having 3 padding bytes between the u8 and the u32 that are not preserved on move / copy / etc.

that's just so much harder to specify, now you have a "bag with gaps"

gnzlbg (Jul 01 2019 at 18:24, on Zulip):

how much harder?

RalfJ (Jul 01 2019 at 18:24, on Zulip):

I dont know any unit I could use to quantify this :P

gnzlbg (Jul 01 2019 at 18:24, on Zulip):

the proposed way of computing the padding is straight forward

RalfJ (Jul 01 2019 at 18:26, on Zulip):

and there is also the cost this has, as we have seen with your ctest problem

RalfJ (Jul 01 2019 at 18:26, on Zulip):

or would fixing this by not making the union "transparent" not help?

gnzlbg (Jul 01 2019 at 18:27, on Zulip):

I mean, my ctest problem was me assuming that repr(transparent) unions wouldn't have any padding

gnzlbg (Jul 01 2019 at 18:28, on Zulip):

I thought that is how repr(Rust) and repr(transparent) unions were implemented, but it turns out this was not the case

RalfJ (Jul 01 2019 at 18:28, on Zulip):

so using repr(C) to kill the padding would help? or not?

gnzlbg (Jul 01 2019 at 18:29, on Zulip):

repr(C) has padding

gnzlbg (Jul 01 2019 at 18:30, on Zulip):

as in, trailing padding, for example

gnzlbg (Jul 01 2019 at 18:31, on Zulip):

C does not require copies to preserve the padding bytes, C++ does (EDIT: for unions)

gnzlbg (Jul 01 2019 at 18:32, on Zulip):

http://port70.net/~nsz/c/c11/n1570.html#note51

gnzlbg (Jul 01 2019 at 18:34, on Zulip):

If we also require copying all union bytes, then we can do a roundtrip with C++ - with C we can't do it anyways.

RalfJ (Jul 01 2019 at 18:37, on Zulip):

oh so trailing padding is already a problem for you

RalfJ (Jul 01 2019 at 18:37, on Zulip):

well yes the entire point of this discussion was to require copying all unions bytes right? or as many as possible anyway^^

RalfJ (Jul 01 2019 at 18:38, on Zulip):

like, say, max-size-of-a-field many bytes

gnzlbg (Jul 01 2019 at 19:46, on Zulip):

the question is, if all fields of the union have a whole in the same bit offset, why copy that on copy ? That hole is not observable through any field access.

RalfJ (Jul 01 2019 at 20:00, on Zulip):

this assumes the union is complete

RalfJ (Jul 01 2019 at 20:00, on Zulip):

at least in C land, it is not uncommon to consider adding a new variant to a union a backwards compatible change

RalfJ (Jul 01 2019 at 20:01, on Zulip):

keeps the library extensible with new options that old clients can just forward, or if they have to handle them error because the tag they see is unknown

gnzlbg (Jul 01 2019 at 20:46, on Zulip):

good point

Last update: Nov 19 2019 at 17:40UTC