3 ms·
You are willing to do things at runtime that C++ would never countenance. What parts of the runtime are non-optional? It seems like you'd be in a weird and prec
by codewright 14y ago
You are willing to do things at runtime that C++ would never countenance. What parts of the runtime are non-optional? It seems like you'd be in a weird and precarious position, as well as lose access to a number of features, if you shut off the GC.
C++ doesn't assume the existence of a GC, because it's designed to make manual or semi-automatic memory management as performant or accessible as possible that mode of operation is better accommodated when the time for performance arises.
D let you shut off the GC too, except now you were "on your own".
What can't be shut-off that happens at runtime?
In C++, "pay only for what you use" isn't really a compiler flag (although some things are), it's a core design principle of the language and it was designed from the ground-up for that.
Adding a few compiler flags for a mode of operation that wasn't designed for from the beginning isn't really the same thing, no?
Further, Rust doesn't accommodate as much variety or control over the concurrency semantics for the sake of promoting the use of tasks. That is unconscionably unacceptable for systems programming where you need to be able to use virtually any approach to concurrency depending on the nature of the problem being solved.
- pcwalton 14y agoIf you don't use the GC, then you can use stack allocation, unique allocation (like std::unique_ptr), arena allocation, or reference counting with smart pointers. You don't give up memory safety; it is still not designed to be possible to have dangling pointers, wild pointers, etc. As an example, I wrote an MP2 decoder that didn't use dynamic allocation or unsafe code at all, and it wasn't particularly unnatural to write in this way. The reason why GC pointers are built into the language is that GC really requires compiler support to do well (with stack maps) and, in particular, to interoperate with the parts of the language that don't require GC in a safe way. You can't just add GC to a language that wasn't designed for it and have it work as well; the best you can do at that point is conservative GC. If you want good GC, that's a decision you need to make early on, and you need to bake it into your language to some extent. (That doesn't mean you need to rely on it though; that's exactly what Rust is trying to prove!) There is very little that is not planned to be able to be shut off, relative to C++. One of the biggest is failure; if your functions fail, then you have to arrange to run all destructors on the stack while your thread exits. (This is similar to C++ exceptions, and are in fact implemented with C++ exceptions under the hood right now, although we plan to change this.) I suppose we could also have a mode whereby we just leak everything on failure to avoid this overhead (basically like -fno-exceptions in GCC; this is pretty much exactly the same tradeoff as C++ offers). I don't think it'd be popular though :)
- codewright 14y agoSadly I'd edited something just as you posted this, so I'll reiterate here: What about building up arbitrary concurrency mechanisms from scratch such as is possible in C and C++? The impression I had from the IRC channel was that very little beyond tasks and a couple more lower-level tools for concurrency would be accommodated.
- pcwalton 14y agoSome of the concurrency mechanisms are built from scratch today. For example, pipes (the new channel communication layer) are entirely written in bare Rust, with no C++ at all. They use atomic operations: https://github.com/mozilla/rust/blob/master/src/libcore/pipes.rs https://github.com/mozilla/rust/blob/master/src/libcore/pipe... Other interesting parts of the runtime that are built using Rust are task spawning (lots of locks): https://github.com/mozilla/rust/blob/master/src/libcore/task/spawn.rs https://github.com/mozilla/rust/blob/master/src/libcore/task... And implementations of mutexes: https://github.com/mozilla/rust/blob/master/src/libcore/private.rs https://github.com/mozilla/rust/blob/master/src/libcore/priv... The current plan is to implement the entire runtime in Rust itself. That includes the userland scheduler. So we will need all the low-level OS primitive mutexes, condition variables, pthread infrastructure, etc. There's no reason we can foresee why this would be particularly difficult; the only reason why it wasn't done this way from the start is for bootstrapping reasons.