3

I recently asked a question around sort of generic enum/structs in C and realized that although I brought up a comparison with the enum possibilities in e.g. Swift and Rust, I don't really understand how those are handled internally to those languages.

For Rust, I found a (rather roundabout) article titled Peeking inside a Rust enum — look for the "But Rust enums aren't just that." heading and then keep scrolling until the "In Rust, it's called a discriminant." part. Eventually that part gets around to basically saying that Rust enums are sort of equivalent to something like this in C:

struct {
   enum actual_options discriminant;
   union {
      /* … various data types/sub-structs corresponding to each option's need… */
   };
};

Is it basically the same with a Swift enum under the hood? I.e. that I should expect an enum to have basically the same memory overhead as a struct of the largest possible option in my enum, plus at least one extra byte to store the tag/discriminant of the overarching case?

I'm also interested in what code gets generated to use whatever sort of underlying structure. I'm assuming it can't really much more fancy/optimized than what you'd do in C for the structure shown above? E.g.

struct raw_enum {
   enum { case1, case2, case3 } tag;
   union {
      struct { int x; int y; } case1_data;
      const char* case2_data;
      struct { float a; double b; void* c; char d; } case3_data;
   };
};


struct raw_enum d;
fill_in_some_value(&d);
if (d.tag == case1) {
  // use `d.case1_data`…
} else if (d.tag == case2) {
  // use `d.case2_data`…
} else if (d.tag == case3) {
  // use `d.case3_data`…
} else {
  // any runtime assertion for an unknown tag that could somehow sneak in???
}

Is that a reasonable approximation to what Swift does in the code it generates around enums?

natevw
  • 16,807
  • 8
  • 66
  • 90
  • 1
    I'm assuming you're asking about enums with associated values here? – Sweeper Jul 15 '21 at 00:55
  • @Sweeper Yes, but if there is a distinction/optimization made for plain enums vs. enums w/associated values I'd consider that somewhat relevant too. – natevw Jul 15 '21 at 05:24
  • [I once used Hopper to disassemble the generated `init(rawValue:)` initialiser.] It seems like enums w/o associated values are just represented as numbers, but I'm not that familiar with reverse-engineering to be sure. In any case, this suggests that these two kinds of enums are handled differently, and the point of my comment was that asking about both could be a bit too broad, and was trying to get you to narrow it down a bit. – Sweeper Jul 15 '21 at 05:32

0 Answers0