Benno Lossin
2025-May-26 15:04 UTC
[PATCH v10 4/5] rust: replace `kernel::c_str!` with C-Strings
On Sat May 24, 2025 at 10:33 PM CEST, Tamir Duberstein wrote:> -/// Creates a new [`CStr`] from a string literal. > +/// Creates a static C string wrapper at compile time. > /// > -/// The string literal should not contain any `NUL` bytes. > +/// Rust supports C string literals since Rust 1.77, and they should be used instead of this macro > +/// where possible. This macro exists to allow static *non-literal* C strings to be created at > +/// compile time. This is most often used in other macros. > +/// > +/// # Panics > +/// > +/// This macro panics if the operand contains an interior `NUL` byte. > /// > /// # Examples > /// > /// ``` > -/// # use kernel::c_str; > +/// # use kernel::c_str_avoid_literals; > /// # use kernel::str::CStr; > -/// const MY_CSTR: &CStr = c_str!("My awesome CStr!"); > +/// const MY_CSTR: &CStr = c_str_avoid_literals!(concat!(file!(), ":", line!(), ": My CStr!")); > /// ``` > #[macro_export] > -macro_rules! c_str { > +macro_rules! c_str_avoid_literals {I don't like this name, how about `concat_to_c_str` or `concat_with_nul`? This macro also is useful from macros that have a normal string literal, but can't turn it into a `c""` one.> + // NB: we could write `($str:lit) => compile_error!("use a C string literal instead");` here but > + // that would trigger when the literal is at the top of several macro expansions. That would be > + // too limiting to macro authors, so we rely on the name as a hint instead. > ($str:expr) => {{ > - const S: &str = concat!($str, "\0"); > - const C: &$crate::str::CStr = match $crate::str::CStr::from_bytes_with_nul(S.as_bytes()) { > - Ok(v) => v, > - Err(_) => panic!("string contains interior NUL"), > - }; > + const S: &'static str = concat!($str, "\0"); > + const C: &'static $crate::str::CStr > + match $crate::str::CStr::from_bytes_with_nul(S.as_bytes()) {Why is this still our CStr?> + Ok(v) => v, > + Err(err) => { > + let _: core::ffi::FromBytesWithNulError = err;Is this really necessary? --- Cheers, Benno> + panic!("string contains interior NUL") > + } > + }; > C > }}; > }
Tamir Duberstein
2025-May-26 22:30 UTC
[PATCH v10 4/5] rust: replace `kernel::c_str!` with C-Strings
On Mon, May 26, 2025 at 11:04?AM Benno Lossin <lossin at kernel.org> wrote:> > On Sat May 24, 2025 at 10:33 PM CEST, Tamir Duberstein wrote: > > +macro_rules! c_str_avoid_literals { > > I don't like this name, how about `concat_to_c_str` or > `concat_with_nul`? > > This macro also is useful from macros that have a normal string literal, > but can't turn it into a `c""` one.Uh, can you give an example? I'm not attached to the name.> > > + // NB: we could write `($str:lit) => compile_error!("use a C string literal instead");` here but > > + // that would trigger when the literal is at the top of several macro expansions. That would be > > + // too limiting to macro authors, so we rely on the name as a hint instead. > > ($str:expr) => {{ > > - const S: &str = concat!($str, "\0"); > > - const C: &$crate::str::CStr = match $crate::str::CStr::from_bytes_with_nul(S.as_bytes()) { > > - Ok(v) => v, > > - Err(_) => panic!("string contains interior NUL"), > > - }; > > + const S: &'static str = concat!($str, "\0"); > > + const C: &'static $crate::str::CStr > > + match $crate::str::CStr::from_bytes_with_nul(S.as_bytes()) { > > Why is this still our CStr?Good question. I'll just revert all the changes here, I don't need to touch this.> > > + Ok(v) => v, > > + Err(err) => { > > + let _: core::ffi::FromBytesWithNulError = err; > > Is this really necessary?No. Reverted in v11.
Benno Lossin
2025-May-26 23:06 UTC
[PATCH v10 4/5] rust: replace `kernel::c_str!` with C-Strings
On Tue May 27, 2025 at 12:29 AM CEST, Tamir Duberstein wrote:> On Mon, May 26, 2025 at 11:04?AM Benno Lossin <lossin at kernel.org> wrote: >> On Sat May 24, 2025 at 10:33 PM CEST, Tamir Duberstein wrote: >> > +macro_rules! c_str_avoid_literals { >> >> I don't like this name, how about `concat_to_c_str` or >> `concat_with_nul`? >> >> This macro also is useful from macros that have a normal string literal, >> but can't turn it into a `c""` one. > > Uh, can you give an example? I'm not attached to the name.There is one in this patch (: diff --git a/rust/kernel/kunit.rs b/rust/kernel/kunit.rs index e5621d596ed3..09148e982f48 100644 --- a/rust/kernel/kunit.rs +++ b/rust/kernel/kunit.rs @@ -58,9 +58,10 @@ macro_rules! kunit_assert { break 'out; } - static FILE: &'static $crate::str::CStr = $crate::c_str!($file); + static FILE: &'static $crate::str::CStr = $crate::c_str_avoid_literals!($file); --- Cheers, Benno
Alice Ryhl
2025-May-28 10:36 UTC
[PATCH v10 4/5] rust: replace `kernel::c_str!` with C-Strings
On Mon, May 26, 2025 at 06:29:46PM -0400, Tamir Duberstein wrote:> On Mon, May 26, 2025 at 11:04?AM Benno Lossin <lossin at kernel.org> wrote: > > > > On Sat May 24, 2025 at 10:33 PM CEST, Tamir Duberstein wrote: > > > +macro_rules! c_str_avoid_literals { > > > > I don't like this name, how about `concat_to_c_str` or > > `concat_with_nul`? > > > > This macro also is useful from macros that have a normal string literal, > > but can't turn it into a `c""` one. > > Uh, can you give an example? I'm not attached to the name.I also think it should be renamed. Right now it sounds like it creates a c string while avoiding literals in the input ... whatever that means. I like Benno's suggestions, but str_to_cstr! could also work? Alice