From 43dd1444b903be15b6976a1d0357eb984fac6c4b Mon Sep 17 00:00:00 2001 From: febo Date: Mon, 6 Oct 2025 01:14:47 +0100 Subject: [PATCH 1/6] Replace std for alloc --- README.md | 7 +++-- sdk/pinocchio/Cargo.toml | 2 +- sdk/pinocchio/src/entrypoint/mod.rs | 28 +++++++++---------- sdk/pinocchio/src/lib.rs | 10 +++---- sdk/pinocchio/src/sysvars/slot_hashes/mod.rs | 8 +++--- sdk/pinocchio/src/sysvars/slot_hashes/test.rs | 3 +- .../src/sysvars/slot_hashes/test_edge.rs | 3 +- .../src/sysvars/slot_hashes/test_raw.rs | 1 - .../src/sysvars/slot_hashes/test_utils.rs | 1 - 9 files changed, 30 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 42cb2f2b..e8e5e4eb 100644 --- a/README.md +++ b/README.md @@ -171,11 +171,12 @@ pub fn process_instruction( By default, Pinocchio is a `no_std` crate. This means that it does not use any code from the standard (`std`) library. While this does not affect how Pinocchio is used, there is a one particular apparent difference. Helpers that need to allocate memory, such as fetching `SlotHashes` -sysvar data, are not available. To enable these helpers, the `std` feature must be enabled when adding -Pinocchio as a dependency: +sysvar data, are not available. To enable these helpers, the `alloc` feature must be enabled when +adding Pinocchio as a dependency: ``` -pinocchio = { version = "0.10.0", features = ["std"] } +pinocchio = { version = "0.10.0", features = ["alloc"] } ``` +The `alloc` feature uses the `alloc` crate. ## Advance entrypoint configuration diff --git a/sdk/pinocchio/Cargo.toml b/sdk/pinocchio/Cargo.toml index 809f5a43..4b74a64f 100644 --- a/sdk/pinocchio/Cargo.toml +++ b/sdk/pinocchio/Cargo.toml @@ -20,7 +20,7 @@ unexpected_cfgs = { level = "warn", check-cfg = [ [features] copy = ["solana-account-view/copy", "solana-address/copy"] cpi = ["dep:solana-instruction-view"] -std = ["solana-address/std"] +alloc = [] [dependencies] solana-account-view = { workspace = true } diff --git a/sdk/pinocchio/src/entrypoint/mod.rs b/sdk/pinocchio/src/entrypoint/mod.rs index e998cd29..81505653 100644 --- a/sdk/pinocchio/src/entrypoint/mod.rs +++ b/sdk/pinocchio/src/entrypoint/mod.rs @@ -5,7 +5,7 @@ pub mod lazy; pub use lazy::{InstructionContext, MaybeAccount}; -#[cfg(not(feature = "std"))] +#[cfg(not(feature = "alloc"))] use core::alloc::{GlobalAlloc, Layout}; #[cfg(target_os = "solana")] @@ -459,8 +459,8 @@ macro_rules! default_panic_handler { /// This macro sets up a default panic handler that logs the location (file, line and column) where /// the panic occurred and then calls the syscall `abort()`. /// -/// This macro can only be used when all crates are `no_std` and the `"std"` feature is disabled. -#[cfg(not(feature = "std"))] +/// This macro can only be used when all crates are `no_std` and the `"alloc"` feature is disabled. +#[cfg(not(feature = "alloc"))] #[macro_export] macro_rules! nostd_panic_handler { () => { @@ -525,12 +525,12 @@ macro_rules! default_allocator { /// A global allocator that does not allocate memory. /// -/// Using this macro with the `"std"` feature enabled will result in a compile error. -#[cfg(feature = "std")] +/// Using this macro with the `"alloc"` feature enabled will result in a compile error. +#[cfg(feature = "alloc")] #[macro_export] macro_rules! no_allocator { () => { - compile_error!("Feature 'std' cannot be enabled."); + compile_error!("Feature 'alloc' cannot be enabled."); }; } @@ -542,8 +542,8 @@ macro_rules! no_allocator { /// /// The program will panic if it tries to dynamically allocate memory. /// -/// This is used when the `"std"` feature is disabled. -#[cfg(not(feature = "std"))] +/// This is used when the `"alloc"` feature is disabled. +#[cfg(not(feature = "alloc"))] #[macro_export] macro_rules! no_allocator { () => { @@ -653,13 +653,13 @@ mod alloc { } } -#[cfg(not(feature = "std"))] +#[cfg(not(feature = "alloc"))] /// An allocator that does not allocate memory. #[cfg_attr(feature = "copy", derive(Copy))] #[derive(Clone, Debug)] pub struct NoAllocator; -#[cfg(not(feature = "std"))] +#[cfg(not(feature = "alloc"))] unsafe impl GlobalAlloc for NoAllocator { #[inline] unsafe fn alloc(&self, _: Layout) -> *mut u8 { @@ -674,13 +674,13 @@ unsafe impl GlobalAlloc for NoAllocator { #[cfg(all(test, not(target_os = "solana")))] mod tests { - extern crate std; + extern crate alloc; - use core::{alloc::Layout, ptr::copy_nonoverlapping}; - use std::{ + use alloc::{ alloc::{alloc, dealloc}, vec, }; + use core::{alloc::Layout, ptr::copy_nonoverlapping}; use super::*; @@ -703,7 +703,7 @@ mod tests { unsafe { let ptr = alloc(layout); if ptr.is_null() { - std::alloc::handle_alloc_error(layout); + alloc::alloc::handle_alloc_error(layout); } AlignedMemory { ptr, layout } } diff --git a/sdk/pinocchio/src/lib.rs b/sdk/pinocchio/src/lib.rs index 51c4afec..7aa54f4d 100644 --- a/sdk/pinocchio/src/lib.rs +++ b/sdk/pinocchio/src/lib.rs @@ -166,10 +166,10 @@ //! code from the standard (`std`) library. While this does not affect how Pinocchio //! is used, there is a one particular apparent difference. Helpers that need to //! allocate memory, such as fetching `SlotHashes` sysvar, are not available. To -//! enable these helpers, the `std` feature must be enabled when adding Pinocchio +//! enable these helpers, the `alloc` feature must be enabled when adding Pinocchio //! as a dependency: //! ```ignore -//! pinocchio = { version = "0.10.0", features = ["std"] } +//! pinocchio = { version = "0.10.0", features = ["alloc"] } //! ``` //! //! ## Advanced entrypoint configuration @@ -208,10 +208,10 @@ //! cargo build-sbf --features bpf-entrypoint //! ``` -#![no_std] +#![cfg_attr(not(test), no_std)] -#[cfg(feature = "std")] -extern crate std; +#[cfg(feature = "alloc")] +extern crate alloc; pub mod entrypoint; pub mod sysvars; diff --git a/sdk/pinocchio/src/sysvars/slot_hashes/mod.rs b/sdk/pinocchio/src/sysvars/slot_hashes/mod.rs index a81fa4bd..1f33053f 100644 --- a/sdk/pinocchio/src/sysvars/slot_hashes/mod.rs +++ b/sdk/pinocchio/src/sysvars/slot_hashes/mod.rs @@ -23,8 +23,8 @@ use crate::{ Address, }; -#[cfg(feature = "std")] -use std::boxed::Box; +#[cfg(feature = "alloc")] +use alloc::{boxed::Box, vec::Vec}; /// `SysvarS1otHashes111111111111111111111111111` pub const SLOTHASHES_ID: Address = Address::new_from_array([ @@ -299,7 +299,7 @@ impl<'a> SlotHashes> { } } -#[cfg(feature = "std")] +#[cfg(feature = "alloc")] impl SlotHashes> { /// Fills the provided buffer with the full `SlotHashes` sysvar data. /// @@ -320,7 +320,7 @@ impl SlotHashes> { /// Allocates an optimal buffer for the sysvar data based on available features. #[inline(always)] fn allocate_and_fetch() -> Result, ProgramError> { - let mut buf = std::vec::Vec::with_capacity(MAX_SIZE); + let mut buf = Vec::with_capacity(MAX_SIZE); unsafe { // SAFETY: `buf` was allocated with capacity `MAX_SIZE` so its // pointer is valid for exactly that many bytes. `fill_from_sysvar` diff --git a/sdk/pinocchio/src/sysvars/slot_hashes/test.rs b/sdk/pinocchio/src/sysvars/slot_hashes/test.rs index bb5a9997..d89f7eaa 100644 --- a/sdk/pinocchio/src/sysvars/slot_hashes/test.rs +++ b/sdk/pinocchio/src/sysvars/slot_hashes/test.rs @@ -9,7 +9,6 @@ use core::{ ptr, }; -extern crate std; use std::io::Write; use std::vec::Vec; @@ -460,7 +459,7 @@ fn test_from_account_info_constructor() { /// `SlotHashes` getters to make sure the view itself works. We do not verify /// that the syscall populated real on-chain bytes, as doing so requires an /// environment outside the scope of host `cargo test`. -#[cfg(feature = "std")] +#[cfg(feature = "alloc")] #[test] fn test_fetch_allocates_buffer_host() { const START_SLOT: u64 = 500; diff --git a/sdk/pinocchio/src/sysvars/slot_hashes/test_edge.rs b/sdk/pinocchio/src/sysvars/slot_hashes/test_edge.rs index 069d8c2c..78ebb5f2 100644 --- a/sdk/pinocchio/src/sysvars/slot_hashes/test_edge.rs +++ b/sdk/pinocchio/src/sysvars/slot_hashes/test_edge.rs @@ -1,6 +1,5 @@ -use crate::{error::ProgramError, sysvars::slot_hashes::*}; -extern crate std; use super::test_utils::{build_slot_hashes_bytes as raw_slot_hashes, make_account_info}; +use crate::{error::ProgramError, sysvars::slot_hashes::*}; #[test] fn test_wrong_key_from_account_view() { diff --git a/sdk/pinocchio/src/sysvars/slot_hashes/test_raw.rs b/sdk/pinocchio/src/sysvars/slot_hashes/test_raw.rs index aa13dbf0..33b02ef6 100644 --- a/sdk/pinocchio/src/sysvars/slot_hashes/test_raw.rs +++ b/sdk/pinocchio/src/sysvars/slot_hashes/test_raw.rs @@ -2,7 +2,6 @@ use super::raw; use super::*; -extern crate std; #[test] fn test_validate_buffer_size() { diff --git a/sdk/pinocchio/src/sysvars/slot_hashes/test_utils.rs b/sdk/pinocchio/src/sysvars/slot_hashes/test_utils.rs index 0c2a18d1..97382e4f 100644 --- a/sdk/pinocchio/src/sysvars/slot_hashes/test_utils.rs +++ b/sdk/pinocchio/src/sysvars/slot_hashes/test_utils.rs @@ -3,7 +3,6 @@ //! freely while production code remains `#![no_std]`. use super::*; -extern crate std; use crate::account::{Account, AccountView}; use core::ptr; use std::vec::Vec; From 8f0fd09dcf35ace6fc7c7c1eb084084fcce62bb4 Mon Sep 17 00:00:00 2001 From: febo Date: Mon, 6 Oct 2025 01:43:18 +0100 Subject: [PATCH 2/6] Enable alloc feature for tests --- Cargo.lock | 1 + sdk/pinocchio/Cargo.toml | 1 + sdk/pinocchio/src/sysvars/slot_hashes/test.rs | 1 - 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index bebf4567..af4b8149 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,6 +55,7 @@ name = "pinocchio" version = "0.9.1" dependencies = [ "five8_const 0.1.4", + "pinocchio", "solana-account-view", "solana-address", "solana-define-syscall", diff --git a/sdk/pinocchio/Cargo.toml b/sdk/pinocchio/Cargo.toml index 4b74a64f..be4547cb 100644 --- a/sdk/pinocchio/Cargo.toml +++ b/sdk/pinocchio/Cargo.toml @@ -32,4 +32,5 @@ solana-program-error = { workspace = true } solana-define-syscall = { workspace = true } [dev-dependencies] +pinocchio = { path = ".", features = ["alloc"] } five8_const = { workspace = true } diff --git a/sdk/pinocchio/src/sysvars/slot_hashes/test.rs b/sdk/pinocchio/src/sysvars/slot_hashes/test.rs index d89f7eaa..10ea092c 100644 --- a/sdk/pinocchio/src/sysvars/slot_hashes/test.rs +++ b/sdk/pinocchio/src/sysvars/slot_hashes/test.rs @@ -459,7 +459,6 @@ fn test_from_account_info_constructor() { /// `SlotHashes` getters to make sure the view itself works. We do not verify /// that the syscall populated real on-chain bytes, as doing so requires an /// environment outside the scope of host `cargo test`. -#[cfg(feature = "alloc")] #[test] fn test_fetch_allocates_buffer_host() { const START_SLOT: u64 = 500; From b1e7a29371cfb5264628b81fd1af9c158c3240ad Mon Sep 17 00:00:00 2001 From: febo Date: Wed, 8 Oct 2025 15:39:34 +0100 Subject: [PATCH 3/6] Improve alloc feature --- Cargo.lock | 1 - sdk/pinocchio/Cargo.toml | 4 +- sdk/pinocchio/src/entrypoint/mod.rs | 56 +++++++++---------- sdk/pinocchio/src/sysvars/slot_hashes/test.rs | 1 + 4 files changed, 29 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index af4b8149..bebf4567 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,7 +55,6 @@ name = "pinocchio" version = "0.9.1" dependencies = [ "five8_const 0.1.4", - "pinocchio", "solana-account-view", "solana-address", "solana-define-syscall", diff --git a/sdk/pinocchio/Cargo.toml b/sdk/pinocchio/Cargo.toml index be4547cb..a6cf88fd 100644 --- a/sdk/pinocchio/Cargo.toml +++ b/sdk/pinocchio/Cargo.toml @@ -18,9 +18,10 @@ unexpected_cfgs = { level = "warn", check-cfg = [ ] } [features] +alloc = [] copy = ["solana-account-view/copy", "solana-address/copy"] cpi = ["dep:solana-instruction-view"] -alloc = [] +default = ["alloc"] [dependencies] solana-account-view = { workspace = true } @@ -32,5 +33,4 @@ solana-program-error = { workspace = true } solana-define-syscall = { workspace = true } [dev-dependencies] -pinocchio = { path = ".", features = ["alloc"] } five8_const = { workspace = true } diff --git a/sdk/pinocchio/src/entrypoint/mod.rs b/sdk/pinocchio/src/entrypoint/mod.rs index 81505653..7bbb297c 100644 --- a/sdk/pinocchio/src/entrypoint/mod.rs +++ b/sdk/pinocchio/src/entrypoint/mod.rs @@ -7,9 +7,6 @@ pub use lazy::{InstructionContext, MaybeAccount}; #[cfg(not(feature = "alloc"))] use core::alloc::{GlobalAlloc, Layout}; - -#[cfg(target_os = "solana")] -pub use alloc::BumpAllocator; use core::{ cmp::min, mem::{size_of, MaybeUninit}, @@ -22,6 +19,9 @@ use crate::{ Address, BPF_ALIGN_OF_U128, MAX_TX_ACCOUNTS, }; +#[cfg(all(target_os = "solana", feature = "alloc"))] +pub use alloc::BumpAllocator; + /// Start address of the memory region used for program heap. pub const HEAP_START_ADDRESS: u64 = 0x300000000; @@ -125,6 +125,7 @@ const STATIC_ACCOUNT_DATA: usize = size_of::() + MAX_PERMITTED_DATA_INC /// manually. /// /// [`crate::nostd_panic_handler`]: https://docs.rs/pinocchio/latest/pinocchio/macro.nostd_panic_handler.html +#[cfg(feature = "alloc")] #[macro_export] macro_rules! entrypoint { ( $process_instruction:expr ) => { @@ -279,9 +280,9 @@ macro_rules! process_accounts { // // Note: The function is marked as `cold` to stop the compiler from optimizing the parsing of // duplicated accounts, which leads to an overall increase in CU consumption. -#[allow(clippy::clone_on_copy)] #[cold] #[inline(always)] +#[allow(clippy::clone_on_copy)] unsafe fn clone_account_info( accounts: *mut AccountView, accounts_slice: *const AccountView, @@ -459,14 +460,12 @@ macro_rules! default_panic_handler { /// This macro sets up a default panic handler that logs the location (file, line and column) where /// the panic occurred and then calls the syscall `abort()`. /// -/// This macro can only be used when all crates are `no_std` and the `"alloc"` feature is disabled. -#[cfg(not(feature = "alloc"))] +/// This macro should be used when all crates are `no_std`. #[macro_export] macro_rules! nostd_panic_handler { () => { /// A panic handler for `no_std`. #[cfg(target_os = "solana")] - #[no_mangle] #[panic_handler] fn handler(info: &core::panic::PanicInfo<'_>) -> ! { if let Some(location) = info.location() { @@ -502,6 +501,7 @@ macro_rules! nostd_panic_handler { /// Default global allocator. /// /// This macro sets up a default global allocator that uses a bump allocator to allocate memory. +#[cfg(feature = "alloc")] #[macro_export] macro_rules! default_allocator { () => { @@ -602,12 +602,27 @@ macro_rules! no_allocator { }; } -#[cfg(target_os = "solana")] -mod alloc { - //! The bump allocator used as the default rust heap when running programs. +#[cfg(not(feature = "alloc"))] +/// An allocator that does not allocate memory. +#[cfg_attr(feature = "copy", derive(Copy))] +#[derive(Clone, Debug)] +pub struct NoAllocator; - extern crate alloc; +#[cfg(not(feature = "alloc"))] +unsafe impl GlobalAlloc for NoAllocator { + #[inline] + unsafe fn alloc(&self, _: Layout) -> *mut u8 { + panic!("** NO ALLOCATOR **"); + } + #[inline] + unsafe fn dealloc(&self, _: *mut u8, _: Layout) { + // I deny all allocations, so I don't need to free. + } +} + +#[cfg(all(target_os = "solana", feature = "alloc"))] +mod alloc { use core::{ alloc::{GlobalAlloc, Layout}, mem::size_of, @@ -653,25 +668,6 @@ mod alloc { } } -#[cfg(not(feature = "alloc"))] -/// An allocator that does not allocate memory. -#[cfg_attr(feature = "copy", derive(Copy))] -#[derive(Clone, Debug)] -pub struct NoAllocator; - -#[cfg(not(feature = "alloc"))] -unsafe impl GlobalAlloc for NoAllocator { - #[inline] - unsafe fn alloc(&self, _: Layout) -> *mut u8 { - panic!("** NO ALLOCATOR **"); - } - - #[inline] - unsafe fn dealloc(&self, _: *mut u8, _: Layout) { - // I deny all allocations, so I don't need to free. - } -} - #[cfg(all(test, not(target_os = "solana")))] mod tests { extern crate alloc; diff --git a/sdk/pinocchio/src/sysvars/slot_hashes/test.rs b/sdk/pinocchio/src/sysvars/slot_hashes/test.rs index 10ea092c..d89f7eaa 100644 --- a/sdk/pinocchio/src/sysvars/slot_hashes/test.rs +++ b/sdk/pinocchio/src/sysvars/slot_hashes/test.rs @@ -459,6 +459,7 @@ fn test_from_account_info_constructor() { /// `SlotHashes` getters to make sure the view itself works. We do not verify /// that the syscall populated real on-chain bytes, as doing so requires an /// environment outside the scope of host `cargo test`. +#[cfg(feature = "alloc")] #[test] fn test_fetch_allocates_buffer_host() { const START_SLOT: u64 = 500; From 2ac88adb262f0e183aa5c26923e5d8b24fbd7f65 Mon Sep 17 00:00:00 2001 From: febo Date: Mon, 13 Oct 2025 09:43:14 +0100 Subject: [PATCH 4/6] Update alloc feature description --- README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index e8e5e4eb..00a91b0f 100644 --- a/README.md +++ b/README.md @@ -166,17 +166,15 @@ pub fn process_instruction( > ⚠️ **Note:** > The `no_allocator!` macro can also be used in combination with the `lazy_program_entrypoint!`. -## Crate feature: `std` +## Crate feature: `alloc` + +The `alloc` feature is enabled by default and it uses the [`alloc`](https://doc.rust-lang.org/alloc/) crate. This provides access to dynamic memory allocation in combination with the `default_allocator`, e.g., required to use `String` and `Vec` in a program. Helpers that need to allocate memory, such as fetching `SlotHashes` sysvar data, are also available. + +When no allocation is needed or desired, the feature can be disabled: -By default, Pinocchio is a `no_std` crate. This means that it does not use any code from the -standard (`std`) library. While this does not affect how Pinocchio is used, there is a one -particular apparent difference. Helpers that need to allocate memory, such as fetching `SlotHashes` -sysvar data, are not available. To enable these helpers, the `alloc` feature must be enabled when -adding Pinocchio as a dependency: ``` -pinocchio = { version = "0.10.0", features = ["alloc"] } +pinocchio = { version = "0.10.0", default-features = false } ``` -The `alloc` feature uses the `alloc` crate. ## Advance entrypoint configuration From e70370764fb9aaf56406b04b3d64d4c8f4542087 Mon Sep 17 00:00:00 2001 From: febo Date: Mon, 13 Oct 2025 09:57:04 +0100 Subject: [PATCH 5/6] Enable no_allocator with alloc --- sdk/pinocchio/src/entrypoint/mod.rs | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/sdk/pinocchio/src/entrypoint/mod.rs b/sdk/pinocchio/src/entrypoint/mod.rs index 7bbb297c..e116fb0c 100644 --- a/sdk/pinocchio/src/entrypoint/mod.rs +++ b/sdk/pinocchio/src/entrypoint/mod.rs @@ -5,9 +5,8 @@ pub mod lazy; pub use lazy::{InstructionContext, MaybeAccount}; -#[cfg(not(feature = "alloc"))] -use core::alloc::{GlobalAlloc, Layout}; use core::{ + alloc::{GlobalAlloc, Layout}, cmp::min, mem::{size_of, MaybeUninit}, ptr::with_exposed_provenance_mut, @@ -523,17 +522,6 @@ macro_rules! default_allocator { }; } -/// A global allocator that does not allocate memory. -/// -/// Using this macro with the `"alloc"` feature enabled will result in a compile error. -#[cfg(feature = "alloc")] -#[macro_export] -macro_rules! no_allocator { - () => { - compile_error!("Feature 'alloc' cannot be enabled."); - }; -} - /// A global allocator that does not dynamically allocate memory. /// /// This macro sets up a global allocator that denies all dynamic allocations, while allowing static @@ -543,7 +531,6 @@ macro_rules! no_allocator { /// The program will panic if it tries to dynamically allocate memory. /// /// This is used when the `"alloc"` feature is disabled. -#[cfg(not(feature = "alloc"))] #[macro_export] macro_rules! no_allocator { () => { @@ -602,17 +589,15 @@ macro_rules! no_allocator { }; } -#[cfg(not(feature = "alloc"))] /// An allocator that does not allocate memory. #[cfg_attr(feature = "copy", derive(Copy))] #[derive(Clone, Debug)] pub struct NoAllocator; -#[cfg(not(feature = "alloc"))] unsafe impl GlobalAlloc for NoAllocator { #[inline] unsafe fn alloc(&self, _: Layout) -> *mut u8 { - panic!("** NO ALLOCATOR **"); + panic!("** NoAllocator::alloc() does not allocate memory **"); } #[inline] From 5836eec29e162334023caae98a69074ca3afafcf Mon Sep 17 00:00:00 2001 From: febo Date: Mon, 13 Oct 2025 14:20:25 +0100 Subject: [PATCH 6/6] Tweaks --- Cargo.toml | 2 +- README.md | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 46f11ea4..5b2849a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ rust-version = "1.84" [workspace.dependencies] five8_const = "0.1.4" -pinocchio = { version = "0.9", path = "sdk/pinocchio" } +pinocchio = { version = "0.9", default-features = false, path = "sdk/pinocchio" } pinocchio-log-macro = { version = "0.5", path = "sdk/log/macro" } quote = "1.0" regex = "1" diff --git a/README.md b/README.md index 00a91b0f..1a693af3 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,9 @@ When no allocation is needed or desired, the feature can be disabled: pinocchio = { version = "0.10.0", default-features = false } ``` +> ⚠️ **Note:** +> The `default_allocator` macro is not available when disabling the `alloc` feature. + ## Advance entrypoint configuration The symbols emitted by the entrypoint macros — program entrypoint, global allocator and default panic handler — can only be defined once globally. If the program crate is also intended to be used as a library, it is common practice to define a Cargo [feature](https://doc.rust-lang.org/cargo/reference/features.html) in your program crate to conditionally enable the module that includes the `entrypoint!` macro invocation. The convention is to name the feature `bpf-entrypoint`.