I'm essentially looking for malloc/free in Rust.
I found alloc::heap, but when I try to use it I get the following error:
main.rs:1:1: 1:19 error: unstable feature
main.rs:1 ![feature(alloc)]
note: this feature may not be used in the stable release channel
If you want to do it in high-level Rust (RAII, memory safety, bounds checking), you should allocate by creating a Vec. You can optionally use into_boxed_slice to disable resizing the container. See the book's FFI example (specifically the uncompress function) for an example of using Vec as an allocator.
Either use a nightly Rust or you will have to use libc::funcs::c95::stdlib::malloc(size: size_t) from the libc crate. You'll have to transmute the result of course.
Related
I'm trying to use Arc in my code, but as i read the document, there is 2 places Arc is defined: std crate and alloc crate. So, what is the different between alloc::sync::Arc and std::sync::Arc?
From the alloc crate documentation:
This library provides smart pointers and collections for managing heap-allocated values.
This library, like libcore, normally doesn’t need to be used directly since its contents are re-exported in the std crate. Crates that use the #![no_std] attribute however will typically not depend on std, so they’d use this crate instead.
So there's no difference between std::sync::Arc and alloc::sync::Arc.
alloc also provides Box, Vec, String, the collections module, and basically anything in the standard library that requires allocations (hence alloc) but not an underlying OS (filesystem, networking, etc). alloc is there if you want to write bare-metal (unhosted) software that still gets to use the nice standard library data structures.
I'm currently in the progress of learning Rust. I'm mainly using The Rust Programming Language book and this nice reference which relates Rust features/syntax to C++ equivalents.
I'm having a hard time understanding where the core language stops and the standard library starts. I've encountered a lot of operators and/or traits which seems to have a special relationship with the compiler. For example, Rust has a trait (which from what I understand is like an interface) called Deref which let's a type implementing it be de-referenced using the * operator:
fn main() {
let x = 5;
let y = Box::new(x);
assert_eq!(5, x);
assert_eq!(5, *y);
}
Another example is the ? operator, which seems to depend on the Result and Option types.
Can code that uses those operators can be compiled without the standard library? And if not, what parts of the Rust language are depending on the standard library? Is it even possible to compile any Rust code without it?
The Rust standard library is in fact separated into three distinct crates:
core, which is the glue between the language and the standard library. All types, traits and functions required by the language are found in this crate. This includes operator traits (found in core::ops), the Future trait (used by async fn), and compiler intrinsics. The core crate does not have any dependencies, so you can always use it.
alloc, which contains types and traits related to or requiring dynamic memory allocation. This includes dynamically allocated types such as Box<T>, Vec<T> and String.
std, which contains the whole standard library, including things from core and alloc but also things with further requirements, such as file system access, networking, etc.
If your environment does not provide the functionality required by the std crate, you can choose to compile without it. If your environment also does not provide dynamic memory allocation, you can choose to compile without the alloc crate as well. This option is useful for targets such as embedded systems or writing operating systems, where you usually won't have all of the things that the standard library usually requires.
You can use the #![no_std] attribute in the root of your crate to tell the compiler to compile without the standard library (only core). Many libraries also usually support "no-std" compilation (e.g. base64 and futures), where functionality may be restricted but it will work when compiling without the std crate.
DISCLAIMER: This is likely not the answer you're looking for. Consider reading the other answers about no_std, if you're trying to solve a problem. I suggest you only read on, if you're interested in trivia about the inner workings of Rust.
If you really want full control over the environment you use, it is possible to use Rust without the core library using the no_core attribute.
If you decide to do so, you will run into some problems, because the compiler is integrated with some items defined in core.
This integration works by applying the #[lang = "..."] attribute to those items, making them so called "lang items".
If you use no_core, you'll have to define your own lang items for the parts of the language you'll actually use.
For more information I suggest the following blog posts, which go into more detail on the topic of lang items and no_core:
Rust Tidbits: What Is a Lang Item?
Oxidizing the technical interview
So yes, in theory it is possible to run Rust code without any sort of standard library and supplied types, but only if you then supply the required types yourself.
Also this is not stable and will likely never be stabilized and it is generally not a recommended way of using Rust.
When you're not using std, you rely on core, which is a subset of the std library which is always (?) available. This is what's called a no_std environment, which is commonly used for some types of "embedded" programming. You can find more about no_std in the Rust Embedded book, including some guidance on how to get started with no_std programming.
I am trying to extract bits of code from an embedded rust example that does not compile. A lot of these old embedded examples don't compile because they use nightly and they quickly become broken and neglected.
let mut buffer : [u8; 2048] = [0;2048];
// some code to fill the buffer here
// say we want to split the buffer at position 300
let (request_buffer, response_buffer) = buffer.split_mut_at(300);
This example uses #![no_std] so there is no standard library to link to and must have compiled at some point so the function split_mut_at must have worked at some point. I am using IntelliJ rust AND Visual Studio Code as the IDE but neither IDE's can point me to the definition of the split_mut_at function. There is a minefield of crates and use statements in the example and there is no clear way to pin-point where some function comes without huge trial and error effort.
btw, split_at_mut can usually be found in std::string::String
Is there a rust command that tells you what crate a function belongs to in your project? It always takes so long to update rust-docs when doing a rust update. Surely that can help!
You're looking for slice::split_at_mut (note the mut at the end). It is listed in the nightly docs here and the stable docs here. It is also indeed available with #![no_std]. It is defined in libcore here.
As a general rule of thumb when a function x from core or std has a mutable and immutable variant, the function requiring a immutable reference is named x and the function requiring a mutable reference is named x_mut.
I was reading an article which says that Rust has a compiler option to disable heap allocation:
Rust has a number of standard library features that rely on the heap,
like boxes. However, Rust has compiler directives to completely
disable any heap-using language features, and statically verify that
none of these features are being used. It is entirely practical to
write a Rust program with no heap usage.
The ability to check for any mistaken heap allocations at compile-time would be very valuable to me. Exactly how do you do this in Rust? I don't see any relevant flags in the rustc man page.
There is no such compiler flag, although I don't think that's what the article meant:
Rust has compiler directives
I'd parse "directive" as an attribute, something like #[foo]. There's still no attribute that I'm aware of that accomplishes this goal.
Note that your article predates Rust 1.0:
Rust, version 0.11
The closest you can get is to avoid using the standard library and only using the core library. This eschews the use of liballoc, the primary mechanism for allocation. Doing this prevents types like Box or String from even existing, which is a pretty strong static guarantee.
#![no_std]
pub fn example() {
Box::new(42);
}
error[E0433]: failed to resolve. Use of undeclared type or module `Box`
--> src/lib.rs:4:5
|
4 | Box::new(42);
| ^^^ Use of undeclared type or module `Box`
However, nothing can stop you from rewriting the same code that is in liballoc and allocating memory yourself. You could also link against existing libraries that allocate memory. There's no magic compiler pass that detects heap allocation.
See also:
Is it possible to use Box with no_std?
This is the serialize crate, and this is the rustc-serialize crate.
I'm getting deprecation warnings from the compiler when using the Encodable and Decodable traits from the serialize crate. The compiler tells me to use RustcEncodable and RustcDecodable from the rustc-serialize crate.
It seems like this just makes things less readable for the same functionality (apart from base64 encoding provided in rustc-serialize). What's the difference between these crates?
The serialize crate is an internal part of the standard Rust distribution. It won't be available in the Rust 1.0 stable/beta channels.
The rustc-serialize crate used to be serialize, but it was moved out to a separate repository and uploaded to crates.io so that it can evolve on its own.
This was done because the utility of rustc-serialize is enormous but it was not realistic to get it stabilized in time for Rust 1.0. Since the Rust distribution will prohibit unstable features on the stable channel, the only way to continue using the serialization infrastructure is to 1) stabilize what we have or 2) move it to crates.io, where the unstable restrictions don't apply.
rustc-serialize has a lot of known downsides, and it is being worked on, so stabilizing what was there really isn't an option.
But the Decodable/Encodable features require compiler support (because compiler plugins won't be stable either for Rust 1.0). As a stopgap measure, RustcDecodable/RustcEncodable were invented as a temporary measure for the rustc-serialize crate to use explicitly. It's a bit weird, but it leaves the Decodable/Encodable names available for a future backwards-compatible version of a serialize crate that is better than what we have now (perhaps this is what serde2 will become from the aforementioned link).
So for the time being, stick to use rustc-serialize and RustcDecodable/RustcEncodable.
(I apologize that I can't come up with a link to cite all of this. It's knowledge I've accrued over time from GitHub issues. Maybe there is an RFC that lays all of this out though. I can't remember.)
To expand on BurntSushi5's answer, as of the time of this writing, the Rust compiler in both Stable and Beta channels throws the following error when attempting to use vanilla serialize:
error: use of unstable library feature 'rustc_private': deprecated in favor of rustc-serialize on crates.io (see issue #27812)
--> src/main.rs:2:1
|
2 | extern crate serialize;
| ^^^^^^^^^^^^^^^^^^^^^^^
The linked Github issue is not very helpful. In short, use rustc-serialize.