On 14.08.24 14:36, Alice Ryhl wrote: > On Wed, Aug 14, 2024 at 2:29 PM Danilo Krummrich <dakr@xxxxxxxxxx> wrote: >> >> On Wed, Aug 14, 2024 at 10:42:28AM +0200, Alice Ryhl wrote: >>> On Mon, Aug 12, 2024 at 8:25 PM Danilo Krummrich <dakr@xxxxxxxxxx> wrote: >>>> +#[macro_export] >>>> +macro_rules! kvec { >>>> + () => ( >>>> + { >>>> + $crate::alloc::KVec::new() >>>> + } >>>> + ); >>>> + ($elem:expr; $n:expr) => ( >>>> + { >>>> + $crate::alloc::KVec::from_elem($elem, $n, GFP_KERNEL) >>>> + } >>>> + ); >>>> + ($($x:expr),+ $(,)?) => ( >>>> + { >>>> + match $crate::alloc::KBox::new([$($x),+], GFP_KERNEL) { >>>> + Ok(b) => Ok($crate::alloc::KBox::into_vec(b)), >>>> + Err(e) => Err(e), >>> >>> Hmm. This currently generates code that: >>> >>> 1. Creates the array. >>> 2. Allocates the memory. >>> 3. Moves the array into the box. >>> >>> Whereas the stdlib macro swaps step 1 and 2. You can do the same by >>> utilizing new_uninit. A sketch: >>> >>> match KBox::<[_; _]>::new_uninit(GFP_KERNEL) { >>> Ok(b) => Ok(KVec::from(KBox::write(b, [$($x),+]))), >>> Err(e) => Err(e), >>> } >> >> Generally, I'm fine changing that, but what's the reason for the suggestion? It >> shouldn't make a difference, does it? > > The compiler is much more likely to not put the array on the stack > before it is copied to the heap. > > In the case where $x constructs new values, it also avoids > create-then-destroy on allocator failure. If we are this worried about not putting the array on the stack, then we could also do this using `init!`, but the macro still would need to count the number of elements in the array. @Danilo, from the other thread: > How do we get the size here? `#![feature(generic_arg_infer)]` seems to be > unstable. You can use a macro to count the number of elements: macro_rules! count_exprs { () => { 0 }; ($e:expr $(,$rest:expr)* $(,)?) => { 1 + count_exprs!($($rest,)*) }; } And then do match KBox::<[_; count_exprs!($($x),+)]>::new_uninit(GFP_KERNEL) { Ok(b) => Ok(KVec::from(KBox::write(b, [$($x),+]))), Err(e) => Err(e), } --- Cheers, Benno