[−][src]Attribute Macro proconio_derive::fastout
#[fastout]
Enables buffering for stdout.
You cannot create a closure containing print!
or println!
in #[fastout]
function. This
is because the closure cannot implement Send
since StdoutLock
, which is not a Send
, is
internally captured into the closure. This causes a trait bound mismatch when used with
function requiring its argument closure to be a Send
, such as std::thread::spawn()
.
use proconio::fastout; use std::thread; #[fastout] fn main() { thread::Builder::new() .stack_size(32 * 1024 * 1024) .spawn(|| { println!("Hi!"); }) .unwrap() .join() .unwrap(); }
It is too conservative to make all of such closures compilation error because it is actually no
problem to use such a closure only inside a single thread. However, since trait bound check is
done after macro expansions, there is no way to check whther the closure is required to be a
Send
or not. And the compiler error message for actual mismatch of a Send
requirement is
too confusing, pointing out codes you didn't write (macro-expanded codes) as an error position.
In conclusion, for user-friendliness, all of them are prohibited for now.
Internally this is the same with
let __proconio_stdout = ::std::io::stdout(); let mut __proconio_stdout = ::std::io::BufWriter::new(__proconio_stdout.lock()); #[allow(unused_macros)] macro_rules! print { ($($tt:tt)*) => { <::std::io::BufWriter<::std::io::StdoutLock<'_>> as ::std::io::Write>::write_fmt( &mut __proconio_stdout, format_args!($($tt)*), ) .unwrap() }; } #[allow(unused_macros)] macro_rules! println { () => { <::std::io::BufWriter<::std::io::StdoutLock<'_>> as ::std::io::Write>::write_all( &mut __proconio_stdout, b"\n", ) .unwrap() }; ($fmt:literal $($tt:tt)*) => { <::std::io::BufWriter<::std::io::StdoutLock<'_>> as ::std::io::Write>::write_fmt( &mut __proconio_stdout, format_args!(::std::concat!($fmt, "\n") $($tt)*), ) .unwrap() }; } let __proconio_res = { // Your code goes here }; <::std::io::BufWriter<::std::io::StdoutLock> as ::std::io::Write>::flush( &mut __proconio_stdout ).unwrap(); return __proconio_res;