diff options
| author | Evan Haas <evan@lagerdata.com> | 2020-12-07 14:20:45 -0800 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-12-10 15:47:56 -0500 |
| commit | 55cac65f957fc374e4e369e26bd338f11b8b37ee (patch) | |
| tree | 2bcef192dc9c996494117fee01a11fbbebd49933 /lib/std | |
| parent | 5a5389128d3d74f02d3697dd317b977c01c5e8c6 (diff) | |
| download | zig-55cac65f957fc374e4e369e26bd338f11b8b37ee.tar.gz zig-55cac65f957fc374e4e369e26bd338f11b8b37ee.zip | |
Support casting enums to all int types.
In C, enums are represented as signed integers, so casting from an enum to an integer
should use the "cast integer to integer" translation code path. Previously it used the
"cast enum to generic non-enum" code path, because enums were not being treated as integers.
Ultimately this can produce zig code that fails to compile if the destination type does not
support the full range of enum values (e.g. translated C code that casts an enum value to an
unsigned integer would fail to compile since enums are signed integers, and unsigned integers
cannot represent the full range of values that signed ones can).
One interesting thing that came up during testing is that the implicit enum-to-int cast that
occurs when an enum is used in a boolean expression was parsed as an (int) by some versions of
the zig compiler, and an (unsigned int) cast by others. Specifically, the following code:
```c
enum Foo {Bar, Baz};
// ...
enum Foo foo = Bar;
if (0 || foo) {
// do something
}
```
When tested on MacOS, Linux, and Windows using a compiler built from the Windows Zig Compiler
Dev Kit, the above code would emit a cast to c_uint:
`if (false or (@bitCast(c_uint, @enumToInt(foo)) != 0)) {}`
However when tested on Windows with a Zig compiler built using MSVC, it produces:
`if (false or (@bitCast(c_int, @enumToInt(foo)) != 0)) {}`
In this particular case I don't think it matters, since a c_int and c_uint will have the same
representation for zero, but I'm not sure if this is ultimately the result of
implementation-defined behavior or something else.
Because of this, I added explicit casts in the `translate_c.zig` tests, to ensure that the
emitted zig source exactly matches across platforms. I also added a behavior test in
`run_translated_c.zig` that uses the old implicit casts from `translate_c.zig` to ensure
that the emitted Zig code behaves the same as the C code regardless of what cast is used.
Diffstat (limited to 'lib/std')
0 files changed, 0 insertions, 0 deletions
