Zig: Allow bitcast of comptime_int

Created on 5 Nov 2020  路  4Comments  路  Source: ziglang/zig

So in certain cases we may want to use a comptime int to describe a bit mask. For example

const CW_USEDEFAULT = @bitCast(i32, 0x80000000);

but this isn't allowed. You also can't use 0x80000000 as a literal because it gets treated as the unsigned value and won't coerce to the signed value. That bit is probably correct but allowing a bitCast to be a back door to that seems like the right thing. And you can have a compile error if you truncate any bits.

proposal

Most helpful comment

Your real problem is trying to use a signed integer to hold a bitmask, the type system is trying to make sure you really know what you're doing by requiring something as verbose as

const CW_USEDEFAULT = @bitCast(i32, @as(u32, 0x80000000));

That bit is probably correct but allowing a bitCast to be a back door to that seems like the right thing.

The right thing is using the proper type. A bitcast is a bit-by-bit reinterpretation of a given value, how it's supposed to work when a comptime_int has infinite bits?

All 4 comments

Your real problem is trying to use a signed integer to hold a bitmask, the type system is trying to make sure you really know what you're doing by requiring something as verbose as

const CW_USEDEFAULT = @bitCast(i32, @as(u32, 0x80000000));

That bit is probably correct but allowing a bitCast to be a back door to that seems like the right thing.

The right thing is using the proper type. A bitcast is a bit-by-bit reinterpretation of a given value, how it's supposed to work when a comptime_int has infinite bits?

Sometimes that's imposed on you by libraries. This is a windows constant that's required to be a signed integer.

Sometimes that's imposed on you by libraries. This is a windows constant that's required to be a signed integer.

Then use the as plus bitcast combo or math.minInt(u32).

@Rageoholic I ran into this exact issue with this exact windows constant just yesterday :)

I'm working on complete autogenerated windows bindings (https://github.com/marler8997/zig-os-windows). My solution to this is I have a comptime function that handles all these cases:

https://github.com/marler8997/zig-os-windows/blob/3c1da1363191bf401f6e0686663d02918f77ec9f/src/gluezig.zig#L16

So it would look like this in code:

const CW_USEDEFAULT = typedConstant(i32, 0x80000000);

typedConstant detects that 0x80000000 cannot fit inside i32, so it tries to cast it to a u32 and then bitcasts it to i32, which essentially becomes this:

return @bitCast(i32, @as(u32, 0x80000000));

It looks like @LemonBoy came up with the same solution and I agree is the correct solution here.

Was this page helpful?
0 / 5 - 0 ratings