Live data from Hacker News

Zig's new bitCast semantics and LLVM back end improvements

ziglang.org

21–30 of 159 posts

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

#21

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

[deleted]

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

#22

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

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.

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

#23
post #8

Earlier quoted context omitted.

IIRC, for "normal" bit widths the codegen basically uses the next larger machine type and preserves zero bits on the high end. An i3 is an i8 with five MSB zeroes (with more custom behavior for "packed" i3 values). It's UB to fill those with non-zero values. For larger bit widths, like u729, you concatenate many large machine types, the compiler generates instructions in an unrolled loop, and the LLVM optimization pa…

I can't imagine any situation where I'd use a u729 instead of a StaticBitSet. For size 729, it would end up backed by a bit_set.Array, not a bit_set.Integer. https://ziglang.org/documentation/master/std/#std.bit_set.St...

I don't program zig, so it's not clear to me if you can use zig's bitsets arithmetically.

Sometimes it's just more clear to work with integers than other representations. Most situations with a state space of N bits have meaningful integer representations, where arithmetic functions on those representations are also meaningful.

For example, CRCs can be written as the remainder from long division of the message by the polynomial. Defining nontrivial cyclic permutations is also much more straightforward as functions on integers than on bitsets.

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

#24

OT: I'm always surprised at how popular Zig discussions get here, or Youtube and other medias. Don't get me wrong, I love Zig and I think it's a great C replacement, but I'm very confused on why C3 or Odin rarely get any attention at all, despite being in the same C-replacement crowd. But still surprised at what Zig does better than these other projects? Is Andrew much better at marketing/promoting the language? He's…

Andrew doesn't strike me as someone who does any marketing at all. He just wants to make the language he wants to use, and does it well.

Sometimes its just right time, right place. But also, Zig has received attention via projects like Ghostty, TigerBeetle, and Bun (prior to rewrite of course)

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

#25

OT: I'm always surprised at how popular Zig discussions get here, or Youtube and other medias. Don't get me wrong, I love Zig and I think it's a great C replacement, but I'm very confused on why C3 or Odin rarely get any attention at all, despite being in the same C-replacement crowd. But still surprised at what Zig does better than these other projects? Is Andrew much better at marketing/promoting the language? He's…

I think Andrew is a big part of it, and the people he surrounded himself with are the other part. What kind of pre-1.0 language hosts conventions? Crazy that they manage to do that. Andrew's vision has always been clear and inspiring to me. I think this got Zig its initial following, and they have capitalized extremely well on it to grow as a community.

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

#26
post #22

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

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.

But doesn't that show why this is a bad idea? If I understand correctly, this code:

  const MyUnion = packed union {
    full: u16,
    bytes: [2]u8,
  };
  const value: u16 = 0x55aa;
  const in_union: MyUnion = @bitCast(value);
  const without_union: [2]u8 = @bitCast(value);
  std.debug.assert(without_union[0] == in_union.bytes[0]);
  std.debug.assert(without_union[1] == in_union.bytes[1]);
...will now succeed or fail depending on the endianness of the target. That looks like the type of footgun that will bring decades of joy.

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

#27

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

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

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

#28

Earlier quoted context omitted.

I can't imagine any situation where I'd use a u729 instead of a StaticBitSet. For size 729, it would end up backed by a bit_set.Array, not a bit_set.Integer. https://ziglang.org/documentation/master/std/#std.bit_set.St...

I don't program zig, so it's not clear to me if you can use zig's bitsets arithmetically. Sometimes it's just more clear to work with integers than other representations. Most situations with a state space of N bits have meaningful integer representations, where arithmetic functions on those representations are also meaningful. For example, CRCs can be written as the remainder from long division of the message by the…

For other situations like a CRC on an arbitrarily-sized message, a big int would be better, surely? You can do long division on those. https://ziglang.org/documentation/0.16.0/std/#std.math.big.i...

I was talking about GP's u729, which is 9*9*9, the state space of a sudoku board. Can you come up with a situation where dividing that number by anything is meaningful?

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

#29
post #20

Earlier quoted context omitted.

I can't imagine any situation where I'd use a u729 instead of a StaticBitSet. For size 729, it would end up backed by a bit_set.Array, not a bit_set.Integer. https://ziglang.org/documentation/master/std/#std.bit_set.St...

Old habits :) If I had to steel-man the idea, I'm pretty sure the integer-based solution has better codegen with many kinds of sparse, comptime-known masks. I think you're right though, StaticBitSet looks better.

For your specific case, even a simple `[9][9]u16` might perform better (where you make use of nine bits in each u16). For each entry, the nine mask bits would be in the same bit positions, so the compiler won't have to do a bunch of shifts to extract/align the bits. CPUs love consistency. I doubt it's worth the additional codegen complexity to save 70 bytes in your data model.

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

#30

OT: I'm always surprised at how popular Zig discussions get here, or Youtube and other medias. Don't get me wrong, I love Zig and I think it's a great C replacement, but I'm very confused on why C3 or Odin rarely get any attention at all, despite being in the same C-replacement crowd. But still surprised at what Zig does better than these other projects? Is Andrew much better at marketing/promoting the language? He's…

Yes, Andrew did a lot of internet cult marketing over the years, and then you have exponential free cult marketing.
Post reply on HN