Zig, the Ideal C Replacement Or?

48 ksec 73 5/11/2025, 10:15:08 AM bitshifters.cc ↗

Comments (73)

SoraNoTenshi · 3h ago
I am not entirely sure what the Author is criticizing? It looks like a comparison to Odin rather than any critic.

And also: I don't quite understand most of the Arguments. UB is often a way to ensure that certain optimizations can be made (if i remember correctly.) Also there just are certain facts that when you have full control over memory, some things can just not be predictable. (Accessing invalid pointers as an example)

Verbosity is mostly subjective. Most of Author's concerns were path lengths, which can easily be "fixed" by redefining the path into a constant. `const debug = std.debug;` I also think the Argument towards "it looks like java's println" full on is a bad argument. Especially because `std.debug.print` does something completely different.

The whole "critic" towards `build.zig` also seems like it's done with without good faith. Yes it's daunting at first. Yes it requires to learn about the build system in the beginning. Sure those are all very real Arguments, author just doesn't want to mention the benefits of it.

Then half of the arguments about comptime i also don't quite understand. It seems like it is building up the main point of the argument, but then you just get hit by a statement. So no explanation no nothing. Talking about lazy evaluation and a little bit of how SoA makes things worse (which i have no clue how that matters in this context) and then saying it's violation "no hidden control flow" is not really getting the point i feel like.

90s_dev · 3h ago
> The whole "critic" towards `build.zig` also seems like it's done with without good faith. Yes it's daunting at first. Yes it requires to learn about the build system in the beginning. Sure those are all very real Arguments, author just doesn't want to mention the benefits of it.

He just pointed out to us language skimmers that it's a potential chicken egg problem, which we may not have considered. Perfect for this kind of article. Whereas pointing out its merits would just be recreating part of ziglang.org

SoraNoTenshi · 53m ago
I mean reading through the article it was only considering author's present perception which is a bit too naïve in my opinion.

Out of my head, the benefits of having a `build.zig` that you learn right from the get go is, that you kind of have to dig a bit into the eco-system a bit. Also how the buildsystem works, etc. which then in return makes it muuuuch easier later on if you have a bigger project, to properly utilize the power of the buildsystem.

I can also only consider my perspective here, but I've done quite a bit of Rust now (and work with it for over a year now, full time as well), and i can tell you as much: I would be thrown into icy waters if i need to do anything with a build.rs.

aeonik · 1h ago
Well theoretically if you compiled the whole system with Zig or Rust, you could eliminate that undefined behavior of invalid pointers right?

You'd need an OS that supports it, but it seems viable that the OS using allocators could know what happens at any given pointer.

To do it statically though, and with enough detail, I suppose it would take something like Idris with dependent types, and I'd imagine at that point it would be a pretty tough exercise.

SoraNoTenshi · 56m ago
I think that'd require a different Datatype than a Raw pointer. Allocating heap memory is a side-effect that's not really predictable, if you take all the factors into account. However i can see a world where this may be possible because of virtual memory, but i don't know how.

Dependent Types could help, although i am unsure if it helps with raw pointers.

stephc_int13 · 3h ago
I've been closely following and evaluating the train of C replacement languages that was (I believe) started by Jonathan Blow and Jai.

Zig is one of the strong contenders, but Odin is IMO following a saner path, Carbon and D should be mentioned and I think there are a few others.

My initial reaction to new programming languages is naturally skeptical, but I really liked the way the designers behind those efforts approached it, trying to solve frequent C/C++ pain points and adding a few fresh ideas.

But overall, after a few years, I am sticking with C and orthodox C++, the cost/benefit ratio is simply not worth the effort, none of them are really mature and the problems they try to solve are not painful enough.

My current take on this is to view Jai/Zig/Odin/etc. as attempted C forks, quite often motivated by hubris and coming with the usual inconvenience of forks, a lot of wasteful/redundant efforts put into small islands, each ruled by their own "benevolent" kings.

An other analogy that can be made is the many attempts at replacing keyboards layouts. Dvorak etc. They probably have their merits, but the adoption was limited to a few enthusiasts for the same reasons that C is unlikely to get replaced by any of those forks.

90s_dev · 3h ago
> My current take on this is to view Jai/Zig/Odin/etc. as attempted C forks, quite often motivated by hubris and coming with the usual inconvenience of forks, a lot of wasteful/redundant efforts put into small islands, each ruled by their own "benevolent" kings.

Didn't Rust do the same thing? We only call efforts wasteful until they become mainstream, then in retrospect we call it excitement driven prudence.

Anyway, is there an "Odin for C programmers" short guide, so I can learn it more quickly?

stephc_int13 · 3h ago
Rust is a bit different, more like a C++ replacement and heavily focused on so-called memory safety, but with IMO many bad design decisions, while I consider Zig/Jai/Odin as merely "meh" I think that Rust is bad.
pdpi · 3h ago
What about Rust's memory safety story justifies the "so-called" qualifier?
stephc_int13 · 2h ago
To be clear, the design is pretty solid. But the marketing and storytelling around it is BS.

This should be called hardening and the whole "unsafe" thing is also detrimental. Computer security and exploits is a highly complex topic, there are no silver bullets. Rust code is safer to some extent, but not "safe" from bugs and exploits.

cadu2 · 3h ago
Can you comment you some of these decisions in Rust that you feel are bad? I enjoy the language and have done quite a bit of work with it so I might be blinded/biased. I feel some warts here and there (async fns, anyone?), but overall the thing works and `cargo` is really a blessing.
stephc_int13 · 2h ago
Horrendous compilation time. Unnecessary complexity everywhere, basically C++ but worse.
bonzini · 1h ago
There's a lot less complexity in Rust than C++. Compilation times are mostly due to lack of compiled code reuse, which is bad but not unsolvable.
heresie-dabord · 2h ago
> the problems they try to solve are not painful enough.

The lack of safety is not painful enough? There is an entire industry (i.e. job sector, training, expertise) that evolved to try to thwart bad actors abusing unsafe languages.

wolvesechoes · 21m ago
But neither Zig nor Odin solve this problem. The only serious attempt is Rust.
pron · 2h ago
I am similarly sceptical, but that's not to say these new languages cannot teach us much. I don't know if Zig or Rust would ever become as popular as C++ -- the odds are certainly stacked against them -- but they both have novel approaches that could, perhaps, introduce some ideas into programming that one day may make an impact.
pjmlp · 2h ago
C replacement languages have been a thing for decades, since 1978 if we don't count its predecessors, unfortunately UNIX/C is hard to beat, thankfully there is also Typescript for C, aka C++.
andrewmcwatters · 3h ago
I feel many of your sentiments, and suspect that many C successors fail, because they don't want to just look like an evolution of C in the same way C with Classes did.

No one is out here building C with Safety.

pjmlp · 2h ago
WG14 could design such an evolutionary path, it has been obvious since 1980's, however they clearly aren't interested.
90s_dev · 3h ago
> Of course, if you don’t use pos, the compiler will say that this is an error and refuse to compile as well. And if you discard that error (typically using _ = pos;), the compiler will complain that it should be a const.

This was one of the main things that bothered me about Zig when I last tried it. This actively works against me when writing prototypes, exploratory code, and especially when writing code to learn the language. I get the rationale, that it's trying to protect me from shipping poorly designed code. But helicopter mom features do not belong in a programming language. They are just as hindering to progress as a literal one would be to a grown man, and for the exact same reasons. I know Andrew has made up his mind, but minds can be changed. So please, Andrew, please take away this helicopter mom feature.

josephg · 3h ago
Urgh this frustrates me so much.

The worst part is, the recommended way to avoid these compilation problems is to add:

    _ = my_unused_variable;
to your code. Some IDE extensions even do this automatically. But if you do that, it permanently suppresses all compiler feedback that my variable is unused! Its basically the worst of all worlds:

- I can't easily prototype, or test code as I go because I keep stubbing my toe on irrelevant unused variables. And these are compilation errors, not warnings.

- In order to test my code, I need to go and fix all the unused variable errors (either automatically or manually). But once I've done that, they're essentially suppressed forever. Now I don't even get warnings, and I'm at risk of shipping code with unused variables. Now I need to manually scan my code, looking for times when _ = x was only added as a placeholder. Will I forget some? You bet.

So I end up in a situation where its both less convenient than other languages (I have to do more work to test my code). AND I'm more likely to ship bad code - since by the time I'm done, half my unused variable warnings have been manually suppressed and I can't find out where they are.

This obviously works for some people. Maybe some people never try running their code as they go. But its just horrible for me. It breaks my workflow and risks me shipping worse code. And it provides no actual benefit in return.

90s_dev · 2h ago
> (I have to do more work to test my code)

I feel like that's already the cultural precedence in Zig. I mean, isn't their primary way of making sure your code fully and oncely frees all memory, just writing tons of tests that thoroughly exercise your function(s)?

josephg · 2h ago
Sure; but when I'm working on a complex problem, I'll often run (test) my code as I go, eyeballing the input and output to make sure I'm on the right track and its doing what I expect. The less time that passes between writing code and discovering a bug, the easier it is to find and fix the bug. Its also a great way to write tests - I'm more aware of edge cases when I've just written the code being tested.

The problem is that zig makes it hard to run the first half of a function or block of code. I've always got variables or parameters that I simply haven't put to use yet.

In an ideal world, my half-written code would fit neatly into a set of well defined functions with no unused variables. But at an experimental stage, I haven't refactored my code to make it beautiful yet. I always prefer to debug my code before refactoring it, because if my tests fail afterwards, I can isolate the bug to the refactoring process itself.

90s_dev · 49m ago
I don't disagree with anything you said, I was adding to it, and showing evidence that it seems to be a problem with Zig community's culture.

> at an experimental stage, I haven't refactored my code to make it beautiful yet. I always prefer to debug my code before refactoring it, because if my tests fail afterwards, I can isolate the bug to the refactoring process itself.

Yes, that is inherently the best way to write code. The right flow is,

1) make it work

2) make it work right

3) make it work for the right reasons

Phil_Latio · 2h ago
I've never even tried Zig because of this: Since the author defends this decision, it begs the question: What else is burried in the Zig language design? I don't know and I don't want to find out.
Icathian · 3h ago
This is the exact same attitude as people who threw tantrums about seatbelt laws in the 90s. It was wrong then, and it's wrong now. For mostly the same reasons.
lolinder · 29m ago
If we're going to go with the seatbelt comparison then we'd have to flesh it out a bit:

Your new car sounds an alarm non-stop if any seat belt in the car is unfastened, whether or not a seat is occupied and whether or not the car is even on. This seems kind of silly, so you raise it with the manufacturer and they say that standard procedure is to just leave all seat belts fastened all the time.

You start doing that and quickly realize that it's much harder to remember to put your seat belt on than it was in your old car, because the car doesn't warn you when you've forgotten your seat belt and when you do remember on your own you have to sit up awkwardly to unfasten it before you can get under it and fasten it around you. You point this out to some fans of the manufacturer and they act like you're the weird one for not seeing how this makes you safer.

90s_dev · 3h ago
Not using a variable is the same as flying out your car window?

It's more like the cashier smacks a peanut out of your hand saying you'll get fat.

dmit · 3h ago
Even when compiling in Debug mode! Where the analogy is closer to a friend who's applying for a cashier job asking you to role play being a customer so they could practice, and then spitting in your face when you go "Hey, Joe! I'll take these" because "No real life customer would do that! Start over."
90s_dev · 3h ago
> Even when compiling in Debug mode! closer to a friend asking you to role play being a customer so they could practice, and then spitting in your face saying "No customer would do that! Start over."

Thanks for the hearty laugh :D

lvass · 3h ago
Seatbelt laws are still wrong, government has no business protecting me from myself.

But even from an utilitarian perspective, compilers do have warnings and they could just have used that.

cornstalks · 2h ago
> Seatbelt laws are still wrong, government has no business protecting me from myself.

If there are multiple people in a car and some choose to wear seatbelts and some choose not to, those who are not wearing seatbelts become a danger to everyone else as their bodies become in-vehicle projectiles.

Sure, I can understand the debate when it's just a single person in a car. But when a person's decision starts impacting others the debate is going to be very hard to win.

dullcrisp · 1h ago
Even if it’s just you, you’d be leaving your mangled corpse on a public road for other people to deal with, which is a nuisance.

Like take the car crash out of the equation and imagine some cars came with an ejector switch that launches you through the windshield at 70 mph. This would not be allowed.

90s_dev · 3h ago
It also protects innocent bystanders from being forced to see your horrifyingly mangled body tossed on the ground in front of them in what could otherwise have either been a crash with no injuries, minimized injuries, or at least contained injuries. Do you still think that law is overstep, if so why? Genuine question, I have no horse in this race and am on the fence myself.
lvass · 2h ago
Because any restriction of freedom is bad in principle and acceptance of those tend to create overreaching, totalitarian states/mafias. There are valid arguments for restricting freedom from an individual to harm another, but making sure no one can see your dead body right after you happen to crash your car definitely isn't one. It is very much infeasible and an absolute helicopter mom type of concern.
techjamie · 2h ago
Keeping with the analogy, yes, you should always wear your seatbelt on public roads (release), but that doesn't mean I feel like I need to buckle up just to move my car while staying in my own driveway (debug).
Icathian · 1h ago
That's reasonable. I think major restrictions that cause you to need to refactor your code when going from debug to release are a footgun and a half, but that'd at least be defensible.
EPWN3D · 40m ago
I think the author's criticism of the named initializer requirement is emblematic of a big problem I have with most new languages. The author says that it makes things like vectors more verbose and awkward, which is true.

My counter to this is: who gives a shit? I'm not writing a vector library or a game engine; I'm writing systems code, and unnamed initializers are harder to read and expose code to subtle bugs. And for what? So that vectors look prettier?

A lot of programming language design seems to prioritize making its own standard library math functions more elegant to implement, which I find to be very irritating, and Zig is a breath of fresh air in this regard.

behnamoh · 3h ago
C is not going anywhere. Neither are C++, Java, and JS (less sure about TS).

One reason is that we've built most of the foundations of modern software already in these languages. New apps pop up all the time but they all rely on ffmpeg, etc.

The only way for a new language like Zig to cement itself is to build foundational software that other programs depend on. I don't think even Rust is moving in that direction (lots of Rust apps, but not so many libs I've had to use in my programs that were written in Rust).

josephg · 2h ago
A language doesn't need to be used in foundational software to be relevant or useful. Go isn't built in the OS either, but its still used by lots of developers to write useful software.

This might be controversial, but I think its fine for small languages to exist, with small followings. Nobody will ever make a browser in Haskell, but its still a work of art. Nobody uses Elm, but React wouldn't exist without it. And so on. Rust is useful on its own. But its also already inspired the C++ language committee to start talking about memory safety a lot more seriously. Thats a big deal!

I'm delighted that languages like Zig exist. If for no other reason than to show that if you're dedicated enough, a lone hobbyist can still invent a language and make it good. (I wish that were still true for web browsers.)

dumah · 2h ago
From my perspective, the adoption for Linux kernel modules, prevalence in the ecosystem of data science my industry relies on, and the explosion of great rust CLI tools satisfies this foundation.

Native rust extensions to provide canonical high quality interfaces for other languages, like Valkey Glide are another example.

Adding on the fact that rust is the fastest or nearly the fastest growing language in terms of users, and I can’t agree with the view that it is not moving in that direction.

jeberle · 2h ago
Ubuntu's move to uutils suggests Rust is not going anywhere.
macintux · 3h ago
Discussion yesterday of Odin, that touched on Zig and D.

https://news.ycombinator.com/item?id=43939520

mitchbob · 3h ago
Previous discussion (9 comments, 2 days ago): https://news.ycombinator.com/item?id=43942094
dustbunny · 3h ago
Some fair criticisms of differing importance, but the tone of the article feels pretty off putting. Almost like the author has some personal gripe against someone affiliated with Zig something.
bonzini · 3h ago
Back when it still had async support, I looked at using Zig in QEMU.

My main qualm with it is that it doesn't try to integrate with existing C programs. The ideal C replacement for me would be a two-way per-file C transpiler, in the same way as the Vala language was. Cython also works the same way even though it's not a C replacement.

Having to know the full set of Zig sources in advance due to error types, and the strong accent on Zig as a build system, are both a non starter for integration in existing large C programs, for example.

davemp · 3h ago
Replacing C != coexisting seamlessly. Exposing an idiomatic C interface by default would handcuff Zig’s own design.

> Having to know the full set of Zig sources in advance due to error types

You can just catch all of the errors and translate them back into errno or whatever homegrown scheme your c project is using.

- - -

Does the zig compiler not support generating .o’s without a build.zig? I like the zig build system so much that I’ve migrated some large projects that will likely never contain a line of zig, so I haven’t felt that pain point.

kristoff_it · 3h ago
> Does the zig compiler not support generating .o’s without a build.zig?

Of course it does, all the build system does is orchestrate invocations to the other basic zig subcommands (`build-exe`, `build-lib`, `build-obj`, etc). You can invoke `zig build-obj` and get an object file in whatever flavor you prefer.

davemp · 1m ago
So you can just extern the functions you want, handle all the errors internally, and stick it into your makefile with?

    %.o: %.zig
        zig build-obj *.zig -o *.o
anonymoushn · 3h ago
You can't have monomorphization or the old async feature if you need to be able to convert individual files to C.
bonzini · 3h ago
You can do it in multiple passes (analysis/dumping IR followed by code generation, with dep files to connect them). It's what Rust does internally with rmeta files.

Mine is not necessarily a criticism of Zig, mind. It's a criticism of what is needed from a C replacement.

jmull · 2h ago
The author hand waves away ReleaseSafe, but does not really seem to understand its usage.

I don't think zig best-practices are written in stone yet, but I would expect ReleaseSafe to be the default in production. Since zig allows turning off/on safety checks on a per-block basis, you only need to pay as much of a performance cost as you want for this.

Actually, this doesn't really come across as a sincere critique of zig. It's more like how a sport fan talks about a rival team (I guess the author must be team Odin). The "first impressions" section is silly.. of course you don't understand how it all works before you've learned anything about it. It might be a bit confusing and have some new patterns. And yes, all the options of the advanced build system is complex, but... you can use the simple build mechanism, or just go with the template for that matter.

Myself, I think there are certainly valid criticisms of zig to make and I don't know if it's ultimately going to amount to something, but you've got to have some knowledge of the subject and not come at it with a predetermined conclusion.

dmit · 2h ago
> I don't think zig best-practices are written in stone yet, but I would expect ReleaseSafe to be the default in production.

Which profile is the default for the Zig compiler itself? What about Bun? TigerBeetle was the only one of the three to use ReleaseSafe by default last I checked? (Edit: in fact, they outright ban ReleaseFast and ReleaseSmall because they care about correctness.) ZLS suggests ReleaseSafe in its README too, if you count it among the prominent Zig projects.

kristoff_it · 1h ago
Zig ships release fast but there's an accepted proposal (not implemented yet) to change unstable builds to be release safe.
dmit · 1h ago
You mean the official nightlies? I like that plan! Should boost coverage by a lot in irl projects.
charlie-83 · 2h ago
Its always interesting to me that other people have such an issue with languages being verbose. I have never really understood why people feel this way. It's just a bit of extra typing. I also think it generally increases code readability. Anyone who dislikes verbose languages care to explain their perspective to me?
weiwenhao · 3h ago
zig ld should be the only cross-linker out there, and I'm considering migrating to zig, for zig ld's sake .

All programming languages that claim to be alternatives to C eventually become themselves, zig is good enough and different enough to not care about being an alternative to C!

pjmlp · 2h ago
That would have been Modula-2 already in 1978, but sadly Acorn, yes the one from ARM, was the only OS vendor adopting it.
GardenLetter27 · 4h ago
The worst part IMO is no decent LSP like rust-analyzer.
hansvm · 4h ago
What does the LSP lack?
GardenLetter27 · 2h ago
When I tried it, it just didn't detect loads of stuff. It reminded me of writing Go years ago.
dvh · 2h ago
Does it run on Arduino?
pron · 3h ago
Because we rarely have objective measures by which to compare programming languages, there is no such thing as "ideal." Some objective measures can include code size, and it is undoubtedly true that switching from Assembly to Python often results in a super-linear reduction in code size, but we rarely see such differences anymore. When we do get some objective comparisons through empirical research -- always many years later -- we also find that usually differences between languages are smaller than many would expect [1]. This isn't surprising and, in fact, it was predicted by Fred Brooks in the 80s. This is because much of the difficulty in constructing algorithms is essential. This is not just due to results in computational complexity about the fundamental difficulty in constructing and analysing programs, but also part of computers' utility. As I once heard a NASA developer say, "computers were built to surprise us; if we knew their output we wouldn't need to build them."

That's a long-winded way of saying that programming language preference is mostly a matter of personal taste as well as more objective but non-intrinsic, "environmental" or social factors. But that doesn't mean that preferences are evenly distributed. Even within a specific domain there may be big disagreements among programmers over which language is "better," but some languages may appeal to significantly more people than others. Programming language designers, at least those who target their language for wide audiences, effectively try to pick tradeoffs that they guess would appeal to many.

This is what makes statements like "but as we all know, it’s not always the best alternative that wins" meaningless. Winning means appealing to more people, i.e. having a good "market fit", whereas "best" has no agreed-upon definition. Like in the famous story about Betamax vs VHS, one had a better picture quality at the expense of recording time, and it turned out that a longer recording time was more important to them than better picture quality. In various debates over programming languages, I often see people frustrated when confronted with the reality that other people prefer different tradeoffs to their own preferred ones.

What the author find surprising or confusing in Zig are things others find desirable (for reasons such as making the language more expressive, simpler, more easily portable, or faster to compile). If you prefer Odin or Rust or Jai -- use them; that different people prefer different languages is very much to be expected. But one of the things I, subjectively, find appealing in Zig has to do with the point made in the post about "high level conveniences" and "abtractions." Over the past several decades, high-level languages have become so fast that in most software it makes little sense to use low-level languages regardless of the "high level conveniences" they may offer. But low-level languages still have a very important role to play when full control over resource usage (especially memory) is needed, such as in constrained environments. That is why I, as someone who does both high and low-level programming, prefer a separation between the two. I probably won't write a large, complex application in any low-level language, and when I do write low-level code, what's important to me is to clearly see what's going on. Anything that hides that from me isn't a convenience but an inconvenience when doing this kind of programming. To me, subjectively, it seems that making low-level languages appear more high level is a mistake -- it hinders low-level programming without offering a truly compelling alternative to a high-level language. Whether my preferences or the author's are more common is something we'll find out in another decade or so.

[1]: One of the things I find annoying -- not only in programming language debates but in science and technology discourse in general -- is invalid extrapolation of valid empirical results. For example, we do have some valid empirical comparisons of TypeScript vs JavaScript or Rust vs. C, but extrapolating from those to conclusions about, say, TypeScript vs. Clojure or Rust vs. Zig requires making unfounded (as yet) assumptions (such as that all untyped languages are alike or that all languages that don't soundly prevent all undefined behaviour are alike).

ksec · 1m ago
>https://news.ycombinator.com/item?id=43939520

Hi pron, I am hoping you could write your thoughts on Odin.

cranberryturkey · 6h ago
gliptic · 4h ago
> Dynamic Typing: Flexible type system with runtime type checking

Uhm, what does this have to do with C/Zig?

cranberryturkey · 2h ago
its another alternative to C
gliptic · 7m ago
It's really not. Looks like something like JS with almost identical syntax.

Also, the compiler (and what else?) isn't even implemented [1].

[1] https://github.com/profullstack/smashlang/blob/master/src/co...

bonzini · 1h ago
It doesn't even distinguish integer and floating point?
trealira · 4h ago
The message I got upon connecting to this site:

> Website Access Prohibited

> Malware Website Warning

> The website you are trying to access is known to host malware and poses a security risk to your computer and network. Please contact your IT help desk to review if you are impacted. If you think you are receiving this message in error, please contact your IT help desk.

I guess you should know your website is seen as a malware vector.

patrakov · 4h ago
Some anti-malware vendors apply this classification to the whole .cc domain.
tmtvl · 3h ago
What did the Cocos Islands do to deserve that? They don't seem to be a den of villainy and cybercrime.
trealira · 4h ago
I see. That might be what's happened, then.