c_str_macro
A c_str! macro for creating C-compatible string literals in Rust.
Repository Health
Technical Analysis
c_str_macro is a tiny, macro-only Rust crate that solves a common FFI papercut: Rust string literals are not implicitly null-terminated, so passing them to a C API requires manually appending "\0", which is easy to forget and error-prone.
The crate’s single c_str! macro takes a plain Rust string literal, appends the terminating zero byte at compile time, and yields a std::ffi::CStr reference ready to hand to C functions. It has no runtime dependencies, works in no_std-friendly contexts through core::ffi, and keeps FFI call sites clean and safe.
What You Get
- The
c_str!macro for producingCStrreferences from string literals - Automatic appending of the terminating 0 byte at compile time
- A
'static, immutable reference that is always safe to pass to C - Zero runtime dependencies — the crate is macro-only
- Use of
core::ffitypes for lightweight, portable FFI
Common Use Cases
- Passing constant strings to C library functions via FFI bindings
- Avoiding manual, error-prone null-termination of literals
- Cleaning up repetitive CStr construction in bindings crates
- Writing readable FFI call sites without unsafe termination bugs
Under The Hood
Architecture — The entire crate is a single source file (src/c_str.rs, mapped as the lib target in Cargo.toml) exporting one macro_rules! macro, c_str!. The macro uses concat!($lit, "\0") to build a null-terminated string constant at compile time and wraps it in an unsafe { CStr::from_ptr(...) } cast to *const core::ffi::c_char. There is no runtime code path — the expansion is pure compile-time construction.
Tech Stack — Plain Rust (edition 2018) targeting core::ffi types, with libc used only as a dev-dependency for the examples and tests. It has no runtime dependencies at all.
Code Quality — The single macro is documented with a doctest example and covered by tests/tests.rs; the crate lints with #![warn(clippy::all)]. The README is candid that the project is maintained on an as-is basis and that the older, adjacent c_string crate is deprecated.
API Design — The surface is about as small and ergonomic as it gets: c_str!("Hello, world!") returns a &CStr ready for FFI, with the terminating byte handled invisibly. The one caveat is that it only accepts string literals (not runtime values), which is inherent to compile-time termination rather than a design flaw.