5 ms·
The real answer is that they're not. It's just that C has a head start of having a 10MB libc already installed on your system, and Rust doesn't. If you compile
by pornel 8y ago
The real answer is that they're not. It's just that C has a head start of having a 10MB libc already installed on your system, and Rust doesn't.
If you compile C with libc statically linked in, it'll make executables as large as Rust's. If you compile Rust for dynamic linking, it'll give you hello world as small as you get from C.
- mahkoh 8y ago"If you compile C with libc statically linked in, it'll make executables as large as Rust's." $ cat test.c && musl-gcc -static -O2 test.c && echo && du -h a.out #include <stdio.h> int main(void) { printf("Hello World\n"); } 20K a.out
- pornel 8y agoI stand corrected. Congrats to MUSL!
- saagarjha 8y agoI would also imagine that the compiler is performing a couple of optimizations that would significantly reduce the resulting binary’s size: the call to printf would likely resolve to puts, which might be further optimized to a raw write call by a smart enough compiler.
- wbl 8y agoAnd possible dead code elimination in the linker.
- wdroz 8y agoWith an "old" gcc I use at work: echo $(gcc --version) && cat test.c && gcc -static -O2 test.c && echo && du -h a.out gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516 ... #include <stdio.h> int main(void) { printf("Hello World\n"); } 796K a.out
- JohnFen 8y ago> If you compile C with libc statically linked in, it'll make executables as large as Rust's. Not in my experience.
- Crinus 8y agoThat might be the case with glibc but other libraries, compilers and OSes do not follow that. A minimal statically compiled C program in OpenWatcom under Windows is around 50KB and a statically compiled C program in MSVC is around 100KB (i do not count GCC/Clang because last time i checked those generate code that rely on msvcrt.dll which actually is a C library that comes with Windows). Other languages do follow a similar pattern too. Free Pascal has its own runtime library which is linked statically to the executable, does not link against libc unless you want to use c library functions (or libraries that themselves may want to link against c), has a much richer library than libc and yet it can create executables around the same size as C (a simple hello world is a 40KB .exe file in FPC). So, no, the reason for C having small executables is not that C has any head start (besides, with the exception of GCC and Clang, no other Windows C compiler in Windows relies on a C libraries that comes with Windows, although some - like MSVC and C++ Builder - can use it as a dynamic library which may or may not be installed system-wide).
- deleted 8y ago[deleted]
- bscphil 8y agoDoes Rust have the same level of support for dynamic linking as C? Genuine question, I don't know the answer. Good support for dynamic linking is crucial for apps that get shipped in Linux distributions.
- cfallin 8y agoYes, in both directions (using a .so, and building a .so in Rust), but IIRC linking to a .so is a bit hairy -- requiring a build.rs (build script) that passes special options to Cargo. Generating a .so is just a different target type to Cargo (cdylib).
- pornel 8y agoTheoretically you could link to a .so with just `#[link(name="soname", kind="dylib")]` in the code. The hairy part is finding the library on the system, and that's a mess that Rust merely inherited. The build scripts are there to run pkg-config, search system lib dirs, and compile a fallback if necessary (next everyone suggests to just have Cargo automatically figure it out, until they see how deep the rabbit hole goes for snowflake libraries like openssl and llvm).
- bscphil 8y agoI guess the critical question is whether it's built up to the point that anyone wants to use it yet. It's one thing to have theoretical support for dynamic linking, but if in practice everyone just ships giant static binaries (which seems to be the emerging default for Go, node, etc), it doesn't help you much.