To clarify what this means, since things can get confusing with subtle differences in wordings:
* stage1 is when zig is built from C++ code[1] (the "bootstrap" compiler) using system C/C++ compiler toolchain.
* stage2 is when zig is built from Zig code[2] using stage1.
* stage3 is when zig is rebuilt from the same Zig code[2] using stage2.
Before today, zig would give you stage1 by default, and you could opt in to stage2 using `-fno-stage1`.
After today, zig gives you stage3 by default, and you can opt in to stage1 using `-fstage1`.
In all three cases, LLVM is being used. Although Zig has started to fully self-host by providing backends that have no dependency on LLVM, none of these fully self-hosted backends are complete.
Why bother self-hosting? Because:
* Zig produces smaller, faster binaries than C++ that use less memory[4]. Case in point: the new self-hosted compiler is 1.5x faster than the C++ implementation and uses 3x less peak RAM.
* Development velocity in Zig is much faster than C++, and debugging is a breeze in comparison due to Zig being much safer than C++ and having better debug tooling. Similarly, comptime features let us add more assertions and debug checks that are not possible in C++.
* Zig compiles much faster than C++.
* Zig cross compiles better than C++ making it easier to create builds of the compiler for every target.
* The self-hosted compiler does not need a softfloat library dependency to support f16 or f128 operations.
* Zig's std lib data structures are incredibly useful, especially compared to the C++ STL.
There are still many known bugs; not every project will be able to upgrade immediately. See the full upgrade guide [3] for help deciding when and how to upgrade.
This is true, but I don't think your point entirely fair either. Zig's design lends itself to writing this style of code. In contrast the usual way(s) C++ is used encourages code that makes these types of optimizations hard/impossible. In practical terms, if you wanted to write fast software, the ergonomics of the language allowing you to use the desired architecture matter a lot.
(Also, you're replying to the primary author of Zig and presenter of that talk, if you weren't aware.)
While ergonomics matter, I don’t believe the question is settled at all - for very high performance applications C++ is the answer for a long time to come.
Hi Andrew, sorry for the unrelated question but where can we find the financial reports of the Zig Software Foundation for 2022? The Finances spreadsheet hasn't been updated for the past half a year:
Here are some features of Zig that make debugging much easier than C++:
* safety checks (equivalent to UBSAN) when triggered, print stack traces that include source code lines and point to the relevant line/column
* one of the safety checks is using the wrong field of an untagged union. This one is so underappreciated. Wrong union field access costs so much time to debug in C++ but it is a breeze in zig, you get a crash explaining the problem with a stack trace immediately, not a corrupt value that causes problems down the road. untagged unions are core part of the strategy that makes zig fast & have a small memory footprint.
* valgrind client request integration[1]. valgrind "just works" better with Zig than C/C++ because zig emits communicates more information about memory regions that are "undefined".
* error return tracing [2]
* segfaults print stack traces
* std.debug has features to collect stack traces in a compact manner and then dump them at a relevant time [3]
* std.heap.GeneralPurposeAllocator detects leaks and prevents memory corruption from Use-After-Free/Double-Free, making debugging easier
Maybe the runtime safety in debug builds? Like for out of bounds, int overflows, etc. In my zig projects those checks have saved me from using a debugger or valgrind in many cases.
I think it's funny that I got downvoted for this! For full clarity: I wasn't suggesting that they _shouldn't_ be called debug tooling, just that it's not what I would call that class of feature, and it seems that other people do call it that.
I'd call tools like ASAN and friends debug tooling. I'm not sure if zig has tooling that doesn't have an analogue in the c++ world, but having them built in to the compiler by default is a notable feature.
Right, defaults matter. The fact sanitizers exist is much less of a game changer than the default behaviour being sanitized.
Because C++ defaults are notoriously all wrong, in programming language design you could usually do worse than consider, "Is there an alternative to what C++ does here by default?" and if there is one, choose that alternative as your default because it's more likely to be correct.
Sometimes C++ helps you out, it might have a keyword "do_it_right" and you can just default to that, if you feel people might want the C++ default behaviour, feel free to reserve "do_it_wrong" in case people wanted that, but in many cases they will never ask you to implement the C++ behaviour because it's just wrong. Examples: "const" in C++ doesn't mean "constant" it means "immutable", so, make immutable your default and offer "mutable" as the option. "explicit" in C++ makes constructors need an explicit cast to be used for conversion, once again of course you want that by default but feel free to reserve "implicit" in case some people are sure they need the C++ behaviour.
C++ frameworks pre-standard used to have better defaults, unfortunately there a majority of people voting that would rather have the wrong defaults, and so here we are, and given how ISO works it won't change.
Those that care know where the knobs are to re-enable those proper defaults, given that for some domains, C++ is going to stay around for a while, regardless of the alternatives.
> * Zig's std lib data structures are incredibly useful, especially compared to the C++ STL.
I think elaborating on this could make for a very interesting article. :-)
(I have a guess already at one item, which is MultiArrayList, something that kind of blew my mind when I first learned about it, and is in my opinion a very impressive testament to both the power and ease of use of Zig's approach to compile-time computation.)
That's pretty sweet, I didn't know C++ could do this now!
Zig's still got it beat handily in simplicity though -- I think what's really cool about Zig's idea of comp-time evaluation is you get something like the power of C++ with something like the simplicity of C.
A smaller binary will not necessarily be faster - specialization can bloat code size, but having a specific version for a given subtype can be much faster. It’s a tradeoff.
We can hardly be expected to watch a 46 minute video on "A Practical Guide to Applying Data-Oriented Design" to find our answer. It seems unpromising on the surface.
Not quite - what you said is true for a hypothetical "stage4" however there is a distinct difference between stage2 and stage3. While they are built from the same source code, and therefore have the same logic, they are lowered by different backends, meaning they will have potentially drastically different performance characteristics depending on the differences between the stage1 and stage2 backend, respectively.
* stage1 is when zig is built from C++ code[1] (the "bootstrap" compiler) using system C/C++ compiler toolchain.
* stage2 is when zig is built from Zig code[2] using stage1.
* stage3 is when zig is rebuilt from the same Zig code[2] using stage2.
Before today, zig would give you stage1 by default, and you could opt in to stage2 using `-fno-stage1`. After today, zig gives you stage3 by default, and you can opt in to stage1 using `-fstage1`.
In all three cases, LLVM is being used. Although Zig has started to fully self-host by providing backends that have no dependency on LLVM, none of these fully self-hosted backends are complete.
Why bother self-hosting? Because:
* Zig produces smaller, faster binaries than C++ that use less memory[4]. Case in point: the new self-hosted compiler is 1.5x faster than the C++ implementation and uses 3x less peak RAM.
* Development velocity in Zig is much faster than C++, and debugging is a breeze in comparison due to Zig being much safer than C++ and having better debug tooling. Similarly, comptime features let us add more assertions and debug checks that are not possible in C++.
* Zig compiles much faster than C++.
* Zig cross compiles better than C++ making it easier to create builds of the compiler for every target.
* The self-hosted compiler does not need a softfloat library dependency to support f16 or f128 operations.
* Zig's std lib data structures are incredibly useful, especially compared to the C++ STL.
There are still many known bugs; not every project will be able to upgrade immediately. See the full upgrade guide [3] for help deciding when and how to upgrade.
[1]: https://github.com/ziglang/zig/tree/master/src/stage1
[2]: https://github.com/ziglang/zig/tree/master/src
[3]: https://github.com/ziglang/zig/wiki/Self-Hosted-Compiler-Upg...
[4]: https://media.handmade-seattle.com/practical-data-oriented-d...