logoalt Hacker News

ozgrakkurttoday at 3:51 PM7 repliesview on HN

> Consider, for instance, bitcasting a [2]u8 to a u16. Under the old semantics, the result of this operation depends on the target endian: on big-endian targets, the first array element became the 8 most significant bits, whereas on little-endian targets, the first array element became the 8 least significant bits. Under the new semantics, because we only care about logical bit representation (which is endian-agnostic), the operation behaves identically on every target:

This is a huge mistake. You would never expect something like bitCast to do this.

I don't understand this approach. Why change something so simple and low level to be complicated and high level?

Just don't allow casting to u24, as it makes no sense unless you define u24 to be u32 sized as I think c standard does.

I think this approach as an idea is bad but at least just add another built-in that implements this higher level idea to not break a simple expectation and current behavior?


Replies

jjmarrtoday at 5:07 PM

> Just don't allow casting to u24, as it makes no sense unless you define u24 to be u32 sized as I think c standard does.

The reason u32->u24 casting must be well defined is because some hardware (e.g. many GPUs, microcontrollers) only have floating point multipliers. A 24 bit unsigned integer (stored in a 32 bit register) can be losslessly converted to a 32 bit float by the hardware, multiplied, then converted back.

This is much faster than doing 32 bit multiplication in software, however, you still need to tell the compiler about this constraint.

show 2 replies
kevin_thibedeautoday at 5:51 PM

GCC has had __int24 for the AVR backend for some time. Useful for larger integers than int16_t while saving 25% over a 32-bit value. C23 does not mandate padding for _BitInt types. It is wrong to assume that will happen or is the optimal implementation for portable code.

show 1 reply
boricjtoday at 4:45 PM

If I understand it correctly, it basically boils down to copying bits from the source to the destination, in order from the least significant bit to the most significant bit. It's not equivalent to C++'s reinterpret_cast.

I'm no Zig expert, but if you want endian-dependent semantics I'd assume either @ptrCast or a packed union would do the job.

show 1 reply
nvme0n1p1today at 4:17 PM

You don't need to use @bitCast for the behavior you're talking about. @ptrCast still exists.

show 1 reply
tialaramextoday at 4:11 PM

> This is a huge mistake. You would never expect something like bitCast to do this.

Is there at least some sort of @transmute or something ? If Zig wants to say "bitCast" means this odd operation, but provides the thing most people actually want under some plausible name that's just an extra thing to learn which seems OK.

AlienRobottoday at 5:28 PM

To me it makes sense. If you don't know what endianness is, it doesn't make sense that a program you write in one programming language works for one target but doesn't work for the other.

I think endianness is the footgun that Zig is solving, rather than Zig being the one introducing a footgun when you deal with endianness.

show 1 reply