-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: enum discriminant ought to be smaller #1647
Comments
Note, C integers are not always i32, the C standard allows them to be different sizes depending on the possible values they can take, but making them i32 will cover most of the cases. Ideally, the size of the discriminant should be allowed to change based on the size of the values it can take, just like it is done in C, so that they can take values outside of the range of i32. |
@kevina thanks for the clarification. Yes, we should adapt C-like enum representation to match precisely what C compilers would do (or as close as we can get). I guess the key point is that C-like enums can be represented differently from enums with data with relative ease. To what extent is the size of integer used for an enum defined in the C spec? Is it all impl. dependent? |
@nikomatsakis yes its mostly impl. dependent. See http://stackoverflow.com/questions/366017/what-is-the-size-of-an-enum-in-c |
This has more to do with us not being LP64 I imagine. Which is to say: our ints are bigger than those in C, on a lot of 64 bit platforms. But we don't have Not really sure what to do about it. Comments welcome. Being LP64 -- that is, demoting our Something about keeping 32-bit integers alive-by-accident longer than necessary just rubs me the wrong way, I guess. It's 2012. I imagine I can buy 64-bit-word phones by now. |
This sounds like an RFC. I guess I slightly favor the current system; "enum is always an int" seems like a simpler rule and if the enum has to contain anything it'll probably be 64 bit aligned anyhow. |
I could see an argument for representing C-like enums as C integers (for compatibility). |
I've been working on making enums smaller. I think what @nikomatsakis and I have converged on is: enum discriminants should be as small as (efficiently) possible, with the option to specify a specific size or C enum compatibility, and a lint warning (like what we already have for Rust's |
There isn't actually a defined ABI for C enums, the size can vary per declaration. There's a C libraries should really be using |
I think it's true (or at least sufficiently true for our purposes) that, given a C enum and given an ABI, there exists an integer type to be used for it. It might vary per enum, and it might not be the same on an AMD64-SysV-based platform and an APCS-based platform, but this is already true for data representations in general. So, a "represent this like C" flag could work. The other thing going on here is Rust's existing knowledge of C representations, which is currently in The other other thing is that I don't know how much of this is actually needed, at least in the short term. |
@jld: there isn't an enum ABI shared between compilers on the platform though - there's no way to represent one like C, you can just represent it like a specific C compiler with specific compiler flags. #include <stdio.h>
enum foo { A, B };
enum bar { C = 256, D, E };
enum baz { F = 8796093022208, G };
int main() {
printf("%zu\n", sizeof(enum foo));
printf("%zu\n", sizeof(enum bar));
printf("%zu\n", sizeof(enum baz));
return 0;
} clang/gcc on x86_64 without flags:
with
If Rust represented them with the smallest size possible, it would be compatible with |
Right, but you can't (in general) link C code compiled with |
I don't believe this is backwards incompatible, renominating. |
just a bug, removing milestone/nomination. |
we are not going to commit to a stable enum representation |
In which case, can this be closed? |
Adjusted the issue title to match the current plans, such as they are. Or should this be about opt-in C-compatible enums? Should a separate issue be opened for whichever one this issue isn't? |
I've found some more context on the ARM enum ABI issue: http://gcc.gnu.org/ml/gcc/2012-02/msg00315.html So there are two variants of the ABI. A quick test for The i386 and MIPS variants of the SysV ABI are handled annoyingly, in the versions of the spec I found: enums are listed as 4 bytes always, and the |
This is in preparation for making discriminants not always be int (#1647), but it also makes compiles for a 64-bit target not behave differently — with respect to how many bits of discriminants are preserved — depending on the build host's word size, which is a nice property to have. We may want to standardize how to abbreviate "discriminant" in a followup change.
Yeah, this was fixed. There are obviously still potential size optimizations for certain sets of variants but the general case is as good as it will get. |
We use
int
noti32
. This is both wasteful and not compatible with C, where enums are always C integers (i32
). We ought to fix this but #1645 makes it hard to do in general.However, we could make this work in the special case of C-like enums, by changing
trans::type_of_tag()
to represent such tags as ints.The text was updated successfully, but these errors were encountered: