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.
Zig's new bitCast semantics and LLVM back end improvements
41–50 of 159 posts
Re: Zig's new bitCast semantics and LLVM back end improvements
#42Earlier quoted context omitted.
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 en…
Re: Zig's new bitCast semantics and LLVM back end improvements
#43> 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…
You don't need to use @bitCast for the behavior you're talking about. @ptrCast still exists.
> Converts a pointer of one type to a pointer of another type. [1]
[1] https://ziglang.org/documentation/master/#toc-ptrCast
So it is not the same.
You could use it to define a function that implements bitCast. Which defeats the purpose of having any @bitCast intrinsic instead of using @mempcy for everything
Re: Zig's new bitCast semantics and LLVM back end improvements
#44OT: 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…
With Zig, I can just import SDL.h and use it without writing a binding. Can I do that in C3 or Odin?
Re: Zig's new bitCast semantics and LLVM back end improvements
#45OT: 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…
With Zig, I can just import SDL.h and use it without writing a binding. Can I do that in C3 or Odin?
Proper enums, proper tagged unions, and often reading the docs can allow the AI to distinguish T * to one of
1. [*]T
2. [:0]T
3. ?T
4. *T
And these are just the most common ones. If you know it’s a read only pointer/array then you can add the const modifier
Re: Zig's new bitCast semantics and LLVM back end improvements
#46Earlier quoted context omitted.
With Zig, I can just import SDL.h and use it without writing a binding. Can I do that in C3 or Odin?
Odin has SDL built into the language (shipped as a vendored library).
There is a mountain of code written in C that you can simply include in Zig without a wrapper dependency and without having to create the wrapper yourself.
Re: Zig's new bitCast semantics and LLVM back end improvements
#47> 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.…
Citation please - every single GPU in the literal world supports integer arithmetic for operating on tid, gid, etc.
Re: Zig's new bitCast semantics and LLVM back end improvements
#48> 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…
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.
> 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 integers than int16_t while saving 25% over a 32-bit value
You can't even do []u24 in zig as far as I can remember and understand anyway so this is only happening in a packed struct context.
C doesn't mandate padding but C compilers allow having pointers and arrays of irregular _BitInt types as far as I can understand.
In this [1] document, in Abi considerations section, it writes that it is defined to have next-power-of-two layout size.
Also here (for RISCV) [2] it seems like it is defined with next-power-of-two layout.
Also the document here (for x86_64) defines it similarly [3]
[1] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2709.pdf
[2] https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/...
[3] https://gitlab.com/x86-psABIs/x86-64-ABI/-/tree/master?ref_t...
Re: Zig's new bitCast semantics and LLVM back end improvements
#49Earlier quoted context omitted.
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 en…
I wonder if packed union also got/will get the same "logical bits" treatment?
Re: Zig's new bitCast semantics and LLVM back end improvements
#50> 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…
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.
It is not feasible for someone to write endian portable code in a language like Zig without understanding what endianness is imo. Regardless of how they change @bitCast there will be other cases that break this like doing @ptrCast + @memcpy.
Also this breaks currently written code that is endian portable and uses @byteSwap like it is done in most other programming languages that do these things.