Live data from Hacker News

Zig's new bitCast semantics and LLVM back end improvements

ziglang.org

71–80 of 159 posts

Re: Zig's new bitCast semantics and LLVM back end improvements

#71
post #4

Interesting read, even as someone who isn't using Zig. I wonder, these arbitrary-width integers... Is it actually even really worth it? My intuition is to prefer manually packing/unpacking things instead (in any language, even C that has bit width for struct fields), because it gives me a better mental picture of the code that is actually generated. Particularly for something like an signed odd-bit integer - what kin…

I love it. Easily one of my favorite things about the language.

Example: shifting more than the width of the shifted integer is illegal behavior in Zig: therefore, the, what, shiftand? let's go with that, the shiftand for a u64 must be a u6 or smaller.

Sounds annoying? No, it's great! Check this out:

    const CodeUnitKind = enum(u2) {
        low, 
        high,
        follow,
        lead,
    };

    const CodeUnit = packed struct(u8) {
        val: u6,
        kind: CodeUnitKind,
    };
It's really nice!

Re: Zig's new bitCast semantics and LLVM back end improvements

#72
post #67

This change + the existing packed struct logic will be great for working with bit packed binary headers w/o having to manually twiddle so much about the bit handling along the way.

It's so interesting to read comments like this and contrast them with the "don't read the code" type of vibes out right now. It feels like half of the developer world is optimizing low-level struct packing and the other half is YOLO'ing 300 KLOC Electron apps. Very confusing.

I know which kind I want to be.

Re: Zig's new bitCast semantics and LLVM back end improvements

#73
post #67

This change + the existing packed struct logic will be great for working with bit packed binary headers w/o having to manually twiddle so much about the bit handling along the way.

It's so interesting to read comments like this and contrast them with the "don't read the code" type of vibes out right now. It feels like half of the developer world is optimizing low-level struct packing and the other half is YOLO'ing 300 KLOC Electron apps. Very confusing.

i think it's perfect: AI allows you to go incredibly deep (you have unlimited access to context to make incredibly impactful surgical changes), or you can go incredibly broad (you have unlimited access to context to tie a mind numbing amount of components together). what shakes out is the middle layer: "infra" between "algorithms" and "product".

though, to be fair, the middle layer itself is composed of this same work. so it's fractal, or turtles all the way down.

Re: Zig's new bitCast semantics and LLVM back end improvements

#74
post #55

Earlier quoted context omitted.

Zig is already great for this with ‘packed struct’ and arbitrary size ints. Allows for very clean protocol creation between systems with known properties. This is another great step in that direction.

you need different packed structs for little- and big-endian data. and casting with little-endian data is a nightmare - you need to reverse-cascade your struct fields to be in accordance with the little-endian bit-pattern. (or have a comptime function that does it for you, of course. but then you lose all declarations for the struct). what should be a simple writing down of a protocol is now a pedantic and error-pron…

This has been largely solved by everyone agreeing to use little endian. There aren't really use cases for wanting to convert between them.

Re: Zig's new bitCast semantics and LLVM back end improvements

#75

Earlier quoted context omitted.

Take the address and deref afterwards, and it's exactly the same. Or to say another way: if you want bits to be reinterpreted raw as if they're in memory, then... put them in memory, then reinterpret them. > You could use it to define a function that implements bitCast. Which defeats the purpose of having any @bitCast intrinsic Yes, and this is one reason @bitCast was changed to have different semantics that are not…

> Take the address and deref afterwards, and it's exactly the same. It is significantly worse to take address and deref afterwards. You have to do something like: @as( const u32, @ptrCast(&x)). instead of just @bitCast(x) > Yes, and this is one reason @bitCast was changed to have different semantics that are not trivially achieved with @ptrCast. This makes sense except breaking existing code that properly handled end…

Your example is incorrect. @ptrCast has the same (similar, if you want to be pedantic to the exclusion of good faith) result rules. If you need @as to @ptrcast, you'd need it to @bitCast as well.

> It is significantly worse to take address and deref afterwards.

How are you measuring worse? Because my understanding from the article is that's exactly the behavior @bitCast used to have. So, instead of worse, it'd be exactly the same?

If you mean it's simply more things that you have to type... You're describing a core language feature as "worse". For all the builtins, some of them can help the compiler emit better code, but can for some doesn't mean will for all. As an example

    const thing: f64 = @floatFromInt(int_ish);
    const result = thing + other_float;
    return @intFromFloat(result);
Could zig auto convert between these types? Yes, absolutely. But it doesn't as a design decision. On some arch, converting between float and int can be very expensive. A competent engineer will ensure they're type converting in a reasonable order. Zig requires this painfully verbose syntax it order to make it painful. Are there times where it's is actually the only reasonable option? yes, but even if there wasn't it'd still need to exist because I'm not rewriting my whole program to avoid a single float conversion. But because it's a bit painful, I will rewrite this one function to make it less painful.

And, yes having already made that exact mistake... I now write better code from the start because there's no way I'm gonna ruin all my beautiful code with a bunch of ugly, annoying, hard to read, casts.

I used to complain about unused variable errors, unhandled enum branch, var unmodified (hint: use const) errors, hell even result ignored or error ignored when I'm trying to test some unrelated single line of code. But now that I'm used to them, I emit better code without thinking. It's made me a better programmer. Is it annoying? abso-fucking-lutely but I'm better now than I used to be, so: worth it; and: thankyou sir can I have another. :D

Re: Zig's new bitCast semantics and LLVM back end improvements

#76
post #55

Earlier quoted context omitted.

you need different packed structs for little- and big-endian data. and casting with little-endian data is a nightmare - you need to reverse-cascade your struct fields to be in accordance with the little-endian bit-pattern. (or have a comptime function that does it for you, of course. but then you lose all declarations for the struct). what should be a simple writing down of a protocol is now a pedantic and error-pron…

This has been largely solved by everyone agreeing to use little endian. There aren't really use cases for wanting to convert between them.

Does that mean there are no file formats thatbuse big endian? And network byte order isn't a thing?

Re: Zig's new bitCast semantics and LLVM back end improvements

#77

Earlier quoted context omitted.

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.

Thanks for the context, but what I am criticising is this part: > it became allowed to use @bitCast to reinterpret a [3]u8 as a u24 This cant't make sense unless u24 is defined to be 24bits in the first place. It is just silly to allow something like this. It would make so much more sense to me if they started disallowing this or just even print a deprecation notice for it for one release version. > Useful for larger…

> This cant't make sense unless u24 is defined to be 24bits in the first place

It's worth remembering that zig is a ~hll that should be platform agnostic. suppose someone built a byte-chip with a 24 bit word. the "new" zig way of doing things will be more portable and slot right in, and support 32- and 16-bit datatypes just fine.

Re: Zig's new bitCast semantics and LLVM back end improvements

#78

> 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-agnosti…

> 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.

@intCast

Re: Zig's new bitCast semantics and LLVM back end improvements

#79
post #67

This change + the existing packed struct logic will be great for working with bit packed binary headers w/o having to manually twiddle so much about the bit handling along the way.

It's so interesting to read comments like this and contrast them with the "don't read the code" type of vibes out right now. It feels like half of the developer world is optimizing low-level struct packing and the other half is YOLO'ing 300 KLOC Electron apps. Very confusing.

Same as it ever was.

Re: Zig's new bitCast semantics and LLVM back end improvements

#80

Earlier quoted context omitted.

> 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.

@intCast

So, since I don't write Zig I had to go look this up, to save anyone else the bother this is what Rust would call an 'as' cast or C programmers might think of as a value cast, it's going to try to make a value which has a similar meaning but of another type, which may be arbitrarily expensive. What people often want here is a transmute, Rust's core::mem::transmute which changes nothing about the bits except what those bits mean, since the bits didn't change and the machine only has bits anyway this is "free".
Post reply on HN