The following code produces one warning but I expected two warnings; one for each time I wrote CString::new("A CString").unwrap().as_ptr()
:
use std::ffi::CString;
use std::os::raw::c_char;
extern "C" {
fn puts(s: *const c_char);
}
macro_rules! mymacro {
() => {
puts(CString::new("A CString").unwrap().as_ptr());
};
}
fn main() {
unsafe {
puts(CString::new("A CString").unwrap().as_ptr());
mymacro!();
}
}
warning: getting the inner pointer of a temporary `CString`
--> src/main.rs:16:49
|
16 | puts(CString::new("A CString").unwrap().as_ptr());
| ---------------------------------- ^^^^^^ this pointer will be invalid
| |
| this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
|
= note: `#[warn(temporary_cstring_as_ptr)]` on by default
= note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
= help: for more information, see https://doc.rust-lang.org/reference/destructors.html
It does evaluate the code twice:
A CString
A CString
What am I misunderstanding?
When I expand the macro, it's clear I have two lines that should emit a warning.
I am using rustc 1.58.1 (db9d1b20b 2022-01-20)