5 ms·
>If Rust had a restricted subset which had a footprint compared to C Take a look at "#![no_std]", a Rust feature. If you do that, your Rust Hello World progra
by dannymi 3y ago
>If Rust had a restricted subset which had a footprint compared to C
Take a look at "#![no_std]", a Rust feature.
If you do that, your Rust Hello World program will have 14 kiB (with no linker optimizations).
>and allows formal verification (including functional requirements)
See <https://rust-formal-methods.github.io/tools.html https://rust-formal-methods.github.io/tools.html>.
Also, the Rust compiler can be used as a library and you can add whatever checks you want like that. See <https://yoric.github.io/post/uom.rs/ https://yoric.github.io/post/uom.rs/> for an example (not used that much).
Also, I like <https://docs.rs/pre/latest/pre/attr.pre.html https://docs.rs/pre/latest/pre/attr.pre.html>. It allows you to define and then mandate specifying textual requirements (in addition to the usual conditionals).
- kragen 3y agonaïvely, 14 kibibytes sounds like a factor of 2½ worse than c: $ cat smallhello.c #include <unistd.h> int main() { char hello[] = "hello, world\n"; write(1, hello, sizeof hello - 1); return 0; } $ diet gcc -Wl,-z,noseparate-code smallhello.c -o smallhello $ strip smallhello $ ls -l smallhello -rwxr-xr-x 1 user user 4864 Feb 9 06:47 smallhello $ ./smallhello hello, world but that's mostly overhead of dietlibc and linux elf rather than overhead of c per se. it's pretty easy to use c to build embedded firmware that fits in 512 or 1024 bytes (though not always advisable) i would argue that this is 'with no linker optimizations' because -z noseparate-code was the default until a few years ago. linker optimizations can save another 200 bytes or so in this case note that this is without dynamic linking. there's no giant standard library being swept under the rug here. most of the executable code in the resulting program is _start pulling in stackgap, which calls find_in_auxvec, __libc_open, __libc_read, __libc_close, __setup_tls, getenv, strstr, and finally main, and strstr in turn calls memcmp (as does getenv) and strlen. main() itself is only 61 bytes of code, __libc_write is 6 bytes, mostly a tail call to __unified_syscall, which is 34 bytes. so we're already looking at overhead that's 40 times the size of the hello-world code itself, which rust apparently expands to 100 times? but possibly not; it's easy to accidentally compile something with c that ends up 14 kilobytes too but basically c's required runtime is just memset() and memcpy(). everything else only gets invoked if you call it explicitly
- steveklabnik 3y agoThe smallest ELF executable for x86_64 rustc has produced is 138 bytes. You can absolutely get rust code as small as you need, you just have to care enough about binary size to put in the work. We do embedded Rust at work, and do care about this.
- kragen 3y agothank you for the update! what options give the 138-byte executable?
- steveklabnik 3y agoOh it was 137, haha. I will link you to this older comment of mine: https://news.ycombinator.com/item?id=29408906 https://news.ycombinator.com/item?id=29408906 See also https://github.com/johnthagen/min-sized-rust https://github.com/johnthagen/min-sized-rust
- steveklabnik 3y agoOh yeah, also: > but basically c's required runtime is just memset() and memcpy(). everything else only gets invoked if you call it explicitly Rust is barely more: https://doc.rust-lang.org/stable/core/ https://doc.rust-lang.org/stable/core/ > memcpy, memmove, memset, memcmp, bcmp, strlen > rust_begin_panic > rust_eh_personality