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

Topic: Should repr(C) enum allow unknown discriminants?


Elichai Turkel (May 19 2020 at 09:49, on Zulip):

Hi,
Unlike C/C++ regular enums(not enum classes) in rust enums require an instance of an enum to have a valid discriminant.
Currently passing a repr(C) enum from rust to C/C++ should be completely safe.
But the reverse might not be, because if the enums get out of sync and you pass a discriminant you haven't updated yet in rust you get UB.
Not only that but regular enums in C/C++ you can easily write whatever int value you want into an enum instance (https://godbolt.org/z/oeZ2Be)
So passing a &mut c_enum_instance into a C/C++ function is also very dangerous.
This is really footgunny IMHO

Maybe we should somehow drop this requirement / allow some Other variant to be added that captures all the unknown discriminants or something else

Some existing discussions I've found:
https://github.com/rust-lang/rust-bindgen/issues/225
https://github.com/google/flatbuffers/issues/5467

Peter Rabbit (May 19 2020 at 10:26, on Zulip):

This is why winapi defines enums as mere typedefs to u32 and the variants as plain integer constants. That and it helps to save on compile time. Also C has a habit of using enums as bitflags and reimplementing all the operators to allow bitwise operations would also take up valuable compile time.

RalfJ (May 20 2020 at 19:57, on Zulip):

then we'd lose all layout optimizations for these enums though

RalfJ (May 20 2020 at 19:58, on Zulip):

and there's probably a good use-case for enums with validity requirements but a guaranteed layout, which is what repr(C) currently does

RalfJ (May 20 2020 at 19:58, on Zulip):

I agree the C is a misnomer though...

RalfJ (May 20 2020 at 19:59, on Zulip):

I dont think we should "allow other variants", at that point it's not an enum in the Rust sense any more but an integer.
but I could imagine renaming repr(C) to something else (repr(union_of_structs) anyone?) to avoid the confusion.

Chris Denton (May 20 2020 at 20:56, on Zulip):

I think it would be better to have a cnum (?) type. Rust enum and C enum have little in common IMHO.

Gary Guo (May 20 2020 at 23:22, on Zulip):

Chris Denton said:

I think it would be better to have a cnum (?) type. Rust enum and C enum have little in common IMHO.

Wouldn't a wrapper type with associated constants do the same?

Chris Denton (May 20 2020 at 23:33, on Zulip):

Sure! My point was that I don't think there's a need to mess about with repr for this.

RalfJ (May 21 2020 at 08:26, on Zulip):

Chris Denton said:

Sure! My point was that I don't think there's a need to mess about with repr for this.

well, messing around with repr is the only way we can solve the problem that people regularly think that repr(C) enums are similar to C enums. That's not an unreasonable assumption, after all -- but it's just wrong.

Last update: Jun 05 2020 at 22:30UTC