4 ms·
1. In practice most embedded toolchains will give you some of the standard library. A standards compliant C++ freestanding library provides new and delete, for
by acconsta 11y ago
1. In practice most embedded toolchains will give you some of the standard library. A standards compliant C++ freestanding library provides new and delete, for example.
2. The libcore allocator API is marked unstable, so even if you go through the trouble of implementing it, how long will it last?
- Manishearth 11y ago> will give you some of the standard library. That's what libcore is. A lot of the stdlib is reexports over libcore. new and delete are C++ isms, their Rust counterparts are `Box::new` (and destructors are automatic). `Box::new`, like `new`, has the OOM issue. If you're okay with that, you are free to link to the `alloc` crate, which gives you `Box` without pulling in additional deps. There are plans for in-place boxing, and AFAICT that API will be available to embedded users.
- dbaupp 11y ago> There are plans for in-place boxing, and AFAICT that API will be available to embedded users. Already exists, unstably: http://doc.rust-lang.org/nightly/core/ops/trait.Placer.html http://doc.rust-lang.org/nightly/core/ops/trait.Placer.html
- acconsta 11y agoJust to be clear, the C++ equivalent of Box is unique_ptr. I don't see equivalents of new and delete, but I might be missing them. I see Box::from_raw and core::ops::Placer. Is that what you mean by in-place boxing? But now there are two problems: You have to manually allocate a buffer of the right size, check if the pointer is null, and box it. For every allocation. Forget a null check? Allocate too small a buffer? Guess what, you've got undefined behavior! It also doesn't generalize to other parts of the standard library. Did you want to use Rust's built in containers in your kernel? Well, sorry, you're going to have to write your own ones that don't panic on allocation failure.
- Manishearth 11y ago> Just to be clear, the C++ equivalent of Box is unique_ptr. Yeah, I mean that it's used like `new` is. We don't have the notion of constructors. > You have to manually allocate a buffer of the right size, check if the pointer is null, and box it. For every allocation. No. With the placement API, you'll be able to use the `box` syntax (which at the moment just supports `Box`, which has OOM issues) for your custom wrapper (i.e., `Box` with OOM support, or whatever). What `box` gives us is that `let x = box make_inner()` would have the returned value of `make_inner()` written directly to the heap location. (Unlike `let x = Box::new(make_inner())`, which may be a move of `make_inner()`) Placer is a part of this (https://github.com/rust-lang/rfcs/blob/master/text/0809-box-and-in-for-stdlib.md https://github.com/rust-lang/rfcs/blob/master/text/0809-box-... is the whole design). from_raw isn't, that's just a useful API for FFI. > Did you want to use Rust's built in containers in your kernel? Well, sorry, you're going to have to write your own ones that don't panic on allocation failure. When you're writing a kernel you're not supposed to be using the standard library at all, just libcore (which exists for this purpose). The same issue exists in C++.
- acconsta 11y agoPlacer looks interesting. I'll try it out. >When you're writing a kernel you're not supposed to be using the standard library at all, just libcore (which exists for this purpose). The same issue exists in C++. Not quite. C++ standard containers are polymorphic on the allocator. That means you're welcome to use std::list or std::string in kernel mode. Just plug in a kernel allocator and you're good to go. There's no technical reason why every Rust core project must reinvent the linked list and the hash map, like every C project.
- Manishearth 11y agohttps://github.com/rust-lang/rfcs/pull/1183 https://github.com/rust-lang/rfcs/pull/1183
- dbaupp 11y ago1. Yes, as I just said, that's essentially libcore. It doesn't literally offer working dynamic allocations, but I don't see how a cross-platform and cross-use-case freestanding library can do that, too many different environments/constraints to encode an built-in allocator. In fact, core says nothing about how allocation has to work or even if it needs to exist. The rustc distribution has the additional `alloc` and `collections` crates layered on top of `core`, which offers some extra functionality when allocation does exist (without assuming other OS support, like IO), and the allocator used is pluggable. (Do you have an example of a standards complaint C++ freestanding standard library?) 2. There will be some way to do this long term. I can offer no guarantees that it will be what's there right now, but something will exist. This is also something that has been on the radar for a long time, but isn't core to the language. In any case, what is in core is essentially just optimising stack usage, all of the sematics it offers can be done with normal function calls, e.g. `Box::new` is literally just a normal function and perfectly implementable in any environment, if you have some allocation routine (the compiler/language doesn't need to know about either). So the unstable libcore functionality is important and desirable, but not killer. There's also the meaning of "allocators" as in allowing `Vec` (etc.) to use some other algorithm than what Rust does by default; again something desirable and been on the radar for a while, but not key to the language. I don't think this needs any new language features, just people to explore the library space. (NB. this is different to what libcore offers now, which is basically what is called "placement new" in C++.)
- acconsta 11y ago>(Do you have an example of a standards complaint C++ freestanding standard library?) Yes, you've probably heard of libstdc++: https://gcc.gnu.org/onlinedocs/libstdc++/faq.html#faq.what_is_libsupcxx https://gcc.gnu.org/onlinedocs/libstdc++/faq.html#faq.what_i... In other words, freestanding C++ allows you to to use new and delete normally (after providing malloc and free). Note that this a minimum requirement. There's nothing stopping you from using STL containers in embedded systems, and people do (especially now that STL containers can take user defined allocators). It seems like Rust is trying to achieve the same result with libcore. That's good! Thanks for clarifying. But now you lose all the nice parts of the standard library, and probably much of the safety. If you want to use Box, you have to manually do the allocation, check the pointer, and construct the box. Buffer too small? Forget the pointer check? Welcome to undefined behavior. If you want a container, you have to roll your own. If you want a container that takes user-defined allocators, I'm not even sure what'd you do.