Join the discussion
Write your take first — we'll ask for email only when you're ready to publish.
- Hacker News
- These posts make you want not only to use Zig, but also to marry it.
No jokes aside, these posts are the best advertisements of the language.
And I truly like their AI stance.
by fithisux - Can I convert a 300-byte message to Base64 with a single instruction? Like:
in: [300]u8; out: [800]u3; out = @bitCast(in);by teo_zero - `u3` would be base 8, i.e. octal---I think you meant to use `[400]u6`?
Aside from that: I'm not familiar with how standard base64 deals with endianness, so I'm not sure if it would match that, but this `@bitCast` would certainly give you a base64 encoding. But it would probably emit pretty terrible code to do that---our lowering of `@bitCast` isn't really optimized for moving around huge amounts of data in one operation! (But maybe LLVM would surprise me.)
by mlugg - FTA: “Under the new semantics, because we only care about logical bit representation (which is endian-agnostic), the operation behaves identically on every target: the first array element becomes the 8 least significant bits”
I wouldn’t call that endian-agnostic. It’s explicitly picking little-endian.
It also makes things look weird for beginners. I know how it works, but in the
example, turning two 3-bit values [abc def] into three 2-bit values [bc fa de] is way less intuitive than turning it into [ab cd ef].test "bitcast [2]u3 to @Vector(3, u2)"by Someone - That's only because we write numbers in big endian.by messe
- The behavior is agnostic of the endianness of the target platform.by gnubison
- > 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?
by ozgrakkurt - I may be damaged from working on IC hardware design and various weird architectures, but I truly can’t comprehend why you’d think this doesn’t make sense.
Yeah, if your architecture doesn’t support 24-bit int it maps to 32-bits. But it also declares that the numbers you’re storing should never be larger than 2^24. It’s about type safety, and also run time checks in safe mode I believe. Bitcasting three bytes to a 24-bit type makes just as much sanse as casting 4 bytes to 32-bit. Theres zero reasons to introduce arbitrary artificial constraints on what you can do based on details of (most of) the underlying architectures, which doesn’t even matter for the operation you’re performing.
by audunw - You don't need to use @bitCast for the behavior you're talking about. @ptrCast still exists.by nvme0n1p1
- 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.
by boricj - > 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.
by tialaramex - 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.
by AlienRobot - 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.
- I understand the reaction, but I don't agree. I suggest reading the associated proposal[0] along with the devlog, and having a real think about what's going on here. I'm responding to you saying that you "don't understand" the approach: reasonable, and resembles my initial reaction.
I was inclined to agree with you, but what decided it for me is that Zig has another mechanism for "reinterpret bytes". It's exposed on the stdlib as std.mem.asBytes, but this is literally a wrapper for the following:
So nothing is lost here: if you need, for whatever reason (and those do exist), to get a raw array of underlying bytes, you absolutely may. Std.mem also has bytesToValue(T, bytes) T, which makes a copy. All the ingredients are there, and this family of mem functions are thin wrappers over builtins, which boil down to pointer casting, dereferencing, and comptime magic.@ptrCast(@alignCast(ptr));Also worth noting: packed structs in Zig are already defined as logically little-endian: the first field is of low significance, the second is above that, and so on. So this makes `@bitCast` consistent with an existing convention of treating integers as logically little-ended, without regard to how they're actually arrayed in memory.
Plus it stands to make low-level bit-twiddling, using oddly-sized integers, optimize better. I like that, especially when what we trade for that is: nothing. Nothing at all, this is a pure win.
I'd even guess it's that rare language update which silently fixes buggy code, where someone figured "well, basically everything is little-endian already" (or just didn't think about it), and now that code works properly on big-endian machines.
by samatman - > 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.
by jjmarr - 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 very hard to dislike.
by epolanski - > 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.
Doesn't matter as neither will see significant adoption.
by wolvesechoes - Zig has a really great backwards compatibility story with C, and it also is a better C compiler even if you don't write a single line of Zig. It's not hard to see why that is popular.by IshKebab
- With Zig, I can just import SDL.h and use it without writing a binding.
Can I do that in C3 or Odin?
by AlienRobot - Zig was the first to appear on my radar. I believe I saw Andrew's first (?) talk called the "The road to Zig 1.0" where he communicated his vision very clearly in a way that must have sounded like the promise of the holy land for C programmers who were stuck in C hellscape. Maybe it was even an earlier video where he talked after a rust talk but it was essentially the same message.
Maybe the best marketing is to establish your vision and stick to it over the years ?
In any case c3 didn't exist, I had never stumbled on a talk of Odin's creator and its syntax seemed more foreign (I only knew C back then) so I started rooting for zig. Even though it's not 1.0 yet, zig seems more ambitious (incremental compilation ! comptime ! translate-c ! logical bitcasting !) and committed to the vision of C companion/replacement. That for me is enough to still be hyped ten years after.
by cassepipe - > I'm very confused on why C3 or Odin rarely get any attention at all, despite being in the same C-replacement crowd
Your observation is valid, and many would say because something smells very fishy with what HN is doing. Zig is pushed at extremely nonsensical levels on HN, despite there being very worthy and interesting language contenders in the category: C3[1], Odin[2], Vlang[3], Dlang[4], Zen C[5], etc...
We rarely get to see news about these other languages, but instead are constantly saturated with and hit over the head with news about Zig (despite all kinds of issues and being beta). And as if people don't have interests in or don't want to see anything about other young or newer languages in the category.
[1]: https://github.com/c3lang/c3c
[2]: https://github.com/odin-lang/odin
[3]: https://freedium-mirror.cfd/https://levelup.gitconnected.com...
(The V Language: The Best Parts of Go, Rust, and Python — All in One)
[4]: https://freedium-mirror.cfd/https://levelup.gitconnected.com...
(The D Language: A Better C/C++ Alternative Only a Few Programmers Know)
by baranul - 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)
by nickmonad - 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.by Iridescent_
- I can only answer for me, and while I do think it's more significant a metric for me, I equally assume it probably has some influence on others as well.
C3 uses :: for namespaces, that makes it a competitor with C++ more than C. Equally Odin's syntax is more at home among python, not systems programming.
The appeal of Zig is it feels like C. To many people, this is a downside. C is very very scary to them. But for people who feel at home in C, it's not a downside.
Additionally, the selling point for both are "c replacement" where the selling point of Zig is "good systems programming language" C is only mentioned by it's users as a heuristic.
If 2 groups are trying to replace a language that people are running away from, and that's their best selling point... I'd assume they're less likely to be as successful as a different language just trying to be as good as it can be.
I've even stopped comparing Zig to C, IMO, it does a disservice to both. And I say that as someone who likes C.
Full disclosure, I need to spend a bit more time with both odin and c3 to know exactly how this compares. But the reason I keep writing Zig, and still love it, is how simple it is. Zig is aggressively insistant on simplicity at the expense of functionally or comfort. The only other high level language I know of that is as aggressive about it's design simplicity is infact C. While I assume it's an accident when C does it, it's definitely not an accident in Zig.
by grayhatter - Writing linkers must be incredibly rewarding - go has its own, there's mold, there's LLD, there's the OG GNU bfd LD and now Zig has one too! I am sure there's a Rust one too - Wild!
Every one of them is faster than the others too lol! Mold for one tries really hard to be GNU ld and to be useful as an independent linker most have to - I guess Zig/Go ones are purpose built so at least those don't duplicate GNU ld compatibility.
by blinkingled - Wait till you hear how many programming languages there areby usrnm
- 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 kind of code gets generated for sign-extension, a presumably common operation?
Does anybody have other experiences with them, one way or the other?
by simonask - If you use LLVM at least, they expand to a lot of code which is repeated on every operation. There’s a point where the inline code will just blow the instruction cache and just create unacceptable binary bloat.by lerno
- IMO they're fantastic. You can write out a bit layout from a CPU's manual fro example and you can just use whatever bit width the manual specifies, and the compiler takes care of figuring out all the underlying manipulation for you. Which results in much more readable code because you don't have to worry about packing/unpacking it because the compiler will do that for you.by ethin
- It's great for defining fancy floats used in machine learning
e.g. https://github.com/zml/zml/blob/33ced8fa078b3c7c8c709bd526ae...
by ismailmaj