4 ms·
> For example, in C I'd be tempted to reuse a buffer allocated for one purpose for another purpose later (a technique known as HEARTBLEED). You can do that in
by dig1 6y ago
> For example, in C I'd be tempted to reuse a buffer allocated for one purpose for another purpose later (a technique known as HEARTBLEED).
You can do that in Java (with byte arrays) or in Common Lisp, so what is the point here? It is not practice in Java, Lisp nor in C and C++.
> It's convenient to have fixed-size buffers for variable-size data (e.g. PATH_MAX) to avoid (re)allocation of growing buffers
This is because OS/Kernel/filesystem guarantee path max size.
> Idiomatic Rust still gives a lot control over memory allocation, and can do basics like memory pools, ... but in general it steers users towards "boring" use or memory.
The same is done by sane C libraries (e.g. glib).
> Every operating system ships some built-in standard C library that is ~30MB of code that C executables get for "free", e.g. a "Hello World" C executable can't actually print anything, it only calls the printf shipped with the OS.
printf is not shipped with the OS, but with libc runtime. It doesn't have to be runtime (author needs to learn why this libc runtime is shared library and not the usually statically linked library) and you can use minimal implementations (musl) if you want static binaries with minimal size.
So you are saying Rust doesn't call (g)libc at all and directly invoke kernel interrupts? Sure, you can avoid this print "overhead" in C with 3-4 lines of inline assembly, but, why?
> Rust by default can inline functions from the standard library, dependencies, and other compilation units.
So do C compiler.
> In C I'm sometimes reluctant to split files or use libraries, because it affects inlining and requires micromanagement of headers and symbol visibility.
Functions doesn't have to be in headers to be inlined.
> C libraries typically return opaque pointers to their data structures, to hide implementation details and ensure there's only one copy of each instance of the struct. This costs heap allocations and pointer indirections. Rust's built-in privacy, unique ownership rules, and coding conventions let libraries expose their objects by value, so that library users decide whether to put them on the heap or on the stack. Objects on the stack can can be optimized very aggressively, and even optimized out entirely.
WTF? Stopped reading after this.
I find this post a random nonsense and I'd urge author to read some serious C book.
- ben0x539 6y agoAny book you'd recommend to back up your claims?
- dig1 6y ago"The C Programming Language" from K&R is something everyone should read, even if they are not fond of C. "Expert C Programming" [1]. Not up to date, but written from a C compiler writer standpoint. A lot of references to why C (and libs) are the way they are. [1] https://www.amazon.com/Expert-Programming-Peter-van-Linden/dp/0131774298 https://www.amazon.com/Expert-Programming-Peter-van-Linden/d...
- carols10cents 6y agoHow does K&R back up the claims you've made here?
- morty_s 6y agoModern C, by Jens Gustedt is one of the best books on C that I have read. That said, I don't think it scratches the surface of backing up the parents claims––though if anyone know of such a text please let me know.
- vll100 6y agoHow about learning some C instead of asking passive aggressive questions all over this discussion?
- ben0x539 6y agoYou'll be relieved to know I've been writing C code of varying quality for like fifteen years on and off. These days I get asked to write Go most of the time and we've gotten rid of the last C codebase we were maintaining a while ago, but I'm always down for discussion of strict aliasing rules or stupid preprocessor tricks.
- scottlamb 6y agoAnd I find your comment to be a super-annoying combination of pedantic and mostly wrong. I'm not going to go through every example but just pick a few: > > For example, in C I'd be tempted to reuse a buffer allocated for one purpose for another purpose later (a technique known as HEARTBLEED). > You can do that in Java (with byte arrays) or in Common Lisp, so what is the point here? It is not practice in Java, Lisp nor in C and C++. C is a really old language with ancient libraries that are still widely used even though they are simply bad by modern standards. For that reason, I roll my eyes when people say something is not practice in C or talk about "sane" C libraries. A big part of working with C is dealing with ancient insanity. You can make much stronger statements about what is idiomatic in Rust (and to some extent Java) simply because it's newer and more cohesive. > > It's convenient to have fixed-size buffers for variable-size data (e.g. PATH_MAX) to avoid (re)allocation of growing buffers > This is because OS/Kernel/filesystem guarantee path max size. I think you've got that backwards. There's an advertised max path size because people wanted to stick paths in fixed-size buffers rather than deal with dynamic allocation. PATH_MAX is fairly arbitrary considering that there are certainly ways of creating and opening files which have paths exceeding that limit. I found this doc talking about this: https://eklitzke.org/path-max-is-tricky https://eklitzke.org/path-max-is-tricky > printf is not shipped with the OS, but with libc runtime. "The OS" doesn't mean "the kernel". Read...anything...even the lackluster wikipedia article about operating systems...and you'll see stuff like GUIs described as part of the OS. They (generally) don't mean those are in the kernel. You can also see this for example in the GNU GPL; they call out "system libraries", which certainly includes libc. > So you are saying Rust doesn't call (g)libc at all and directly invoke kernel interrupts? Sure, you can avoid this print "overhead" in C with 3-4 lines of inline assembly, but, why? Rust's own standard library uses libc's system call wrappers but not stdio. It has its own libraries for buffer management and formatting which provide the safety one would expect of Rust, know how to integrate with Rust's Display trait for formatting arbitrary Rust data structures, etc. You could call libc::printf yourself if you wanted to, but that's not idiomatic. I wrote some Rust code calling libc::vsnprintf just the other day, because I got a format string + va_list from C in a log callback.