7 ms·
As far as I know, zig is the only language that is able to output binaries on par in size w/ C (a hello world in zig is about the same size as a C one, whereas
by lhorie 6y ago
As far as I know, zig is the only language that is able to output binaries on par in size w/ C (a hello world in zig is about the same size as a C one, whereas most other languages can only manage at a minimum an order of magnitude bigger binaries, sometimes several orders of magnitude). Zig interops cleanly w/ C ABI and C toolchains, can also cross compile AND can cross compile C proper. You can even drop all the way down to asm (standard C technically doesn't support this).
I often refer to zig as a "very sharp knife": it's "cool" for new languages to have more safeguards to protect you from yourself, but Zig feels a bit like it goes in opposite direction in the sense that it exposes the underlying plumbing more than most languages. For example, Go and Rust memory allocations and memory layout are fairly opaque; in zig you can control it idiomatically with obsessive precision.
But unlike C, zig offers a host of safety features, like integer overflow checks, compiler-checked optionals and exhaustive switch, as well as a well behaved compile-time system, and a bunch of syntactical sugar ("method" syntax, if/while/block/return expressions, etc).
And unlike C++, zig is a very small language.
- pcwalton 6y agoIt's possible to make very small Rust binaries: https://github.com/johnthagen/min-sized-rust https://github.com/johnthagen/min-sized-rust 8kB for that Rust example, compared to 16kB for my optimized C hello world compiled with GCC. (Not that I think it makes a difference to anything.) Furthermore, how are Rust memory allocations and layout "fairly opaque"?
- anderspitman 6y agoNot parent, but from my perspective implicit RAII might fall into this category, though I suppose that's specific to deallocation. Zig also requires you to pass an allocator to any function that requires dynamic allocation, which while this could be considered a bit extreme, is certainly less "opaque".
- lhorie 6y agoFor example, usually it's not obvious when memory is being freed. I recall a thread about esbuild where the author was saying they had better GC perf from go due to GC happening in a thread whereas in Rust it didn't and it was not clear how to make that happen or if it was even possible. In zig, you can use an arena allocator, you can free things piecemeal while using an arena, you can free the arena on program exit or in a thread, you can enforce a stack allocator, have multiple allocators, etc and because of the orthogonality of the Allocator interface, most of this knowledge is something you can probably pick up within the first 2 hours of zig (assuming you know C). Re: edit about rust binary size. When I say zig is on par w/ C in terms of binary size, I mean I get the small binary with the basic `zig build-exe hello.zig -O ReleaseFast --strip` command, without any attempts at optimization. Do you know if this 8kb number includes the UPX optimization? If so, I'm calling shenanigans :)
- Dylan16807 6y ago"A striped binary built this way is around 8KB." It's before UPX. > I mean I get the small binary with the basic `zig build-exe hello.zig -O ReleaseFast --strip` command, without any attempts at optimization. You could set up all these things in just a few minutes, so it's not a very big deal. If you don't mind 20KB of string formatting code then you don't have to make "any attempts at optimization" either.
- lhorie 6y ago> If you don't mind 20KB of string formatting code So this here is sort of why I brought up binary size. I know hello world size doesn't really say anything about real world, but as I was looking at different languages, a common theme was this defensive "well what d'ya expect from a thing that has [list of features]" tone when the question of binary size got brought up and people didn't know how to make it smaller. A normal rust build has a similar feel. The 8kb binary link above reads a bit like a hacking adventure to unravel the mysteries of yonder. When I read stuff like this By using a C entry point (by added the #![no_main] attribute) , managing stdio manually, and carefully analyzing which chunks of code you or your dependencies include, you can sometimes make use of libstd while avoiding bloated core::fmt. Expect the code to be hacky and unportable, with more unsafe{}s than usual. It feels like no_std, but with libstd. I'm undoubtedly awed at the cleverness of it all, but it's clearly way off the beaten path. I should note that in addition to the zig build command being guessable by a newbie reading through --help, the hello world code itself is also the idiomatic thing a newbie would've reasonably written. And there's really no need for "air quotes", I really put no effort whatsoever in optimizing: I didn't even use `-O ReleaseSmall` Among all the languages I looked at, Zig was somewhat unique in taking a default stance of proactively using compile time as a tool to take stuff away from the binary (in a sort of saint-exupery way). I'm sure with enough effort it's possible to bring down binary sizes for most languages, but not many languages do this with the relentlessness that zig does out of the box.
- Dylan16807 6y ago> So this here is sort of why I brought up binary size. I know hello world size doesn't really say anything about real world, but as I was looking at different languages, a common theme was this defensive "well what d'ya expect from a thing that has [list of features]" tone when the question of binary size got brought up and people didn't know how to make it smaller. Well, what do you expect? How much size does printf add to a Zig binary? > When I read stuff like this You can get the vast majority of the size savings without any of that stuff. This is someone trying to find the absolute minimum, starting with very practical suggestions before getting into itty bitty weeds. I'd suggest pretending the no_main and no_std sections don't exist. Getting down to 50KB or 30KB is just a matter of telling the compiler to optimize for size and stripping unwind information. If you want to keep all the unwind code and information I'm not sure how much space it takes. > with enough effort I will note again that the compiler settings in this repo, while they may be in multiple places, are still a very small one-time effort for a program.
- AndyKelley 6y agofor zig it's 1.8 kB on x86_64-linux with minimal fiddling. i386-windows comes out to 2.5kB. $ cat hello.zig const std = @import("std"); pub fn main() void { std.io.getStdOut().writeAll("Hello, World!\n") catch {}; } $ zig build-exe hello.zig --strip -OReleaseSmall $ zig build-exe hello.zig --strip -OReleaseSmall -target i386-windows $ ldd hello not a dynamic executable $ strip hello $ ./hello Hello, World! $ wine hello.exe Hello, World! $ ls -hl hello hello.exe -rwxr-xr-x 1 andy users 1.8K Mar 10 21:15 hello -rwxr-xr-x 1 andy users 2.5K Mar 10 21:15 hello.exe No min-sized-zig github repository needed.
- steveklabnik 6y agoI work in embedded these days, commented on this topic on Reddit a few days ago: https://www.reddit.com/r/rust/comments/m0irjk/opinions_on_rust_for_hardrealtimesystems/gq9hrj7/ https://www.reddit.com/r/rust/comments/m0irjk/opinions_on_ru...
- FlashBlaze 6y agoWould very much like to read your thoughts on V[0] [0] https://vlang.io/ https://vlang.io/
- lhorie 6y agoHonestly, I was put off by the early marketing hullabaloo, so I haven't looked closely. What's most problematic in my mind is that from what I've seen, I don't feel that the V lead is as forthcoming about issues and limitations as other project leads are. I'd much rather talk to a project lead that will give it to me straight if their stuff doesn't work. From a technical perspective, my understanding is that V similar to Nim, in the sense that it compiles to C source code. That's fine and all, but IMHO, zig has a huge leg up in this area because it does first class cross compilation of C source code to binary form. To my knowledge, no other tool does this (other than maybe cosmopolitan, if you ignore everything outside posix...) If I were to use V, I'd probably end up using `zig cc` as the `cc` for it
- lelanthran 6y ago> zig has a huge leg up in this area because it does first class cross compilation of C source code to binary form. What's the advantage of this? Compilation speed? Doesn't that then mean that zig can't gain compiler improvements the way using an external compiler can? For example, if C is the intermediate language for $HIGH-LEVEL-LANGUAGE, then $HLL benefits every time that the specific C compiler being used is upgraded.
- deleted 6y ago[deleted]
- lhorie 6y agoThe advantage is cross compilation. Gcc and friends are notoriously difficult to setup for cross compilation (so much so that some don't even bother trying and either only offer source or just compile from different machines running the target platforms, and even this can be a bit of an ordeal) Zig uses LLVM under the hood so it does benefit from LLVM upgrades. Also, there's devils in the details. For example, the copy ellision thing is something that required deliberate implementation; it doesn't just come for free if you're naively emitting C.