When adding `#![no_std]` to a library, are there any disadvantages or complications for the users of that library?

天涯浪子 提交于 2021-01-27 06:08:09

问题


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?


回答1:


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!() }


来源:https://stackoverflow.com/questions/57611219/when-adding-no-std-to-a-library-are-there-any-disadvantages-or-complicati

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!