Print to stderr without allocating
This uses:
- A stack allocated buffer
- The C function
snprintfandwrite
#![allow(unused)]
fn main() {
macro_rules! eprintln {
() => { eprintln!("") };
($fmt:expr $(,$arg:expr)*) => {{
use std::ffi::{c_char, c_int};
#[allow(non_camel_case_types)]
type c_size_t = usize;
#[allow(non_camel_case_types)]
type c_ssize_t = isize;
unsafe extern "C" {
fn snprintf(buf: *mut c_char, buf_size: c_size_t, format: *const c_char, ...) -> c_int;
fn write(fildes: c_int, buf: *const c_char, nbyte: c_size_t) -> c_ssize_t;
}
let mut buf = [0; 128];
let fmt = concat!($fmt, "\n\0");
// SAFETY:
// * `buf` is a stack-allocated buffer `buf.as_mut_ptr()` is valid within this block
// * `buf.len()` is statically known
// * I guess ... we can't ensure the format string and passed arguments are correct, so...
// hope for the best!
unsafe {
let n = snprintf(buf.as_mut_ptr(), buf.len(), fmt.as_ptr() as _, $($arg),*);
debug_assert!((n as usize) < buf.len());
_ = write(2, buf.as_ptr(), n as c_size_t);
}
}};
}
eprintln!("I can print without alloc: %d", 42);
eprintln!("I don't need arguments either");
}