I wrote a Rust library. I heard about the no_std
feature and noticed that my library does not use anything from std
that isn't offered by core
and alloc
. So in theory I could just add the #![no_std]
attribute and change a few imports.
But I wonder how this influences the users of my library. Of course, my hope is that by using #![no_std]
, users in no_std
environments can use my crate as well. That's good, of course. But: do users of my library have any disadvantage from my library being no_std
? For example, are they forced to also use #![no_std]
? That would be bad. I wonder because most crates hide no_std
compatibility behind a Cargo feature. And I actually couldn't find anything about this question online.
If there are no disadvantages from using #![no_std]
, then every crate who can work without std
should add that attribute, right?
Adding two negative numbers together? Just add the absolute value of each number together, put a negative sign in front, and you have your answer!
To add integers having the same sign, keep the same sign and add the absolute value of each number. To add integers with different signs, keep the sign of the number with the largest absolute value and subtract the smallest absolute value from the largest. Subtract an integer by adding its opposite.
Addition (usually signified by the plus symbol +) is one of the four basic operations of arithmetic, the other three being subtraction, multiplication and division. The addition of two whole numbers results in the total amount or sum of those values combined.
We will also look at the pronunciation of ‘s’ and ‘es’. When to add ‘s’: The general rule for making a word plural is to add ‘s’: 1 dog, 2 dogs, 3 dogs
However, in some cases we add ‘es’. On this page we look at when to add ‘s’ and when to add ‘es’. We will also look at the pronunciation of ‘s’ and ‘es’.
Notation and terminology. " Addition " and " add " are English words derived from the Latin verb addere, which is in turn a compound of ad "to" and dare "to give", from the Proto-Indo-European root *deh₃- "to give"; thus to add is to give to. Using the gerundive suffix -nd results in "addend", "thing to be added".
For example, are they forced to also use
#![no_std]
?
Not at all. The dependent crate (that is, the crate/project which will consume your crate) will know to find the core
crate required by your dependency, and one will be free to use it as if no_std
was ever involved. The main difference comes from what to expect from this dependency and how many other crates can use it. In other words, the set of crates compatible with your dependency should always be a superset if that dependency is prepared for no_std
.
The readme of KodrAus/rust-nostd, an example of using and testing no_std
in a library, also recommends using no_std
whenever possible for maximum compatibility:
The current design of Rust's standard library is split into a few layers, each building on the assumed platform capabilities of the one below. There's:
std
: the full standard library assumes the presence of threads, a filesystem, and networking. [...]alloc
: the collections layer builds on the core by assuming runtime support for dynamic memory allocation.core
: the core layer makes no (well, not very many) assumptions about the > underlying platform. Just about any target that can run Rust code is supported by core.So when you're designing your library you can make it maximally portable by targeting the lowest layer of the standard library that you can.
The reason some crates put no_std
behind a Cargo feature is because the crate may contain some opt-in functionalities which do require std
, or at the very least alloc
. By conditioning on Cargo features, environments without the standard library can still use the crate, whereas those with std
or alloc
can use an extended API of the crate. An example of "lib.rs" that shows this capability can be seen below.
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "std")]
extern crate core;
#[cfg(feature = "alloc")]
extern crate alloc;
pub fn foo_into_slice(slice: &mut [u8]) { unimplemented!() }
/// Vec requires alloc
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
#[cfg(feature = "alloc")]
pub fn foo_into_vec(vec: &mut Vec<u8>) { unimplemented!() }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With