Hacker News new | ask | show | jobs
by brutt 2230 days ago
Incompatibility between C enums and Rust enums forces to use integers instead, which leads to errors. (Rust doesn't allow to enum variables to be forward compatible, i.e. it cannot have a value outside of enum).
3 comments

I think that's a good thing. A C "enum" is just a shorthand for declaring an int alias and some constants. You can do that in Rust easily enough.

A Rust enum is an actual enumeration type, which C does not have. This is far more powerful.

It's good thing, but it leads to error in code which must talk to C or network, where enum's are not cast in stone.
You really should not be casting data structures sent over the network directly to local data structures, unless you are using capnproto or another zero copy protocol that does that safely.
You can assign any value to a C enum, they literally are just integers.
> Rust doesn't allow to enum variables to be forward compatible, i.e. it cannot have a value outside of enum

AKA Rust's enums are type-safe, not aliases for integers with some named constants.

Rather than Rust's, I'd say the mistake is C's enums. If you don't want enums, don't have them.

I guess that's one place where Go did something good: they didn't want to improve on C's enums with proper ADTs so they just stripped out the entire thing, an "enum" is an integer and a bunch of constants. Which you can also use to represent these non-enums in Rust though it doesn't have the iota / step convenience. A simple recursive macro might be able to handle it though.

To future proof an enum in rust you use the #[non_exhaustive] annotation.

For C compatibility you have lots of options like #[repr(C)] or #[repr(i32)] to be C compatible. So not sure what you are referring to?

The problem is that #[repr(C)] enum is not compatible with C, even with #[non_exhaustive] annotation, and will never be, because C enum can be described in Rust terms as:

  #[repr(C)]
  enum Foo {
    A = 1, 
    B = 2,
    C = 3,
    UNKNOWN(i32),
  }
which is not possible to define in current version of Rust.