In C++, you can undefine and redefine a macro. For example, a common thing to do in video games is to redefine the logging macro to nothing in Release mode. This guarantees that the code completely disappears which helps with performance.
Is there a way to do a similar thing in Rust?
Basically you might do:
macro_rules! log_if_dbg {
(...) => (if cfg!(debug_assertions) { /* do logging */ })
}
This is how the macro debug_assert!
is implemented. The doc says:
Unlike assert!, debug_assert! statements are only enabled in non optimized builds by default. An optimized build will omit all debug_assert! statements unless -C debug-assertions is passed to the compiler. This makes debug_assert! useful for checks that are too expensive to be present in a release build but may be helpful during development.
This is the same as your situation, only for assert, not logging. Looking at the source:
macro_rules! debug_assert {
($($arg:tt)*) => (if cfg!(debug_assertions) { assert!($($arg)*); })
}
This has also been briefly discussed on the Rust users forum, where the summary is that cfg(debug_assertions)
is the way to check if we're in debug mode.
I have no idea how stable cfg(debug_assertions)
is, however.
You would use conditional compilation attributes:
#[cfg(feature = "debugging")]
macro_rules! log {
() => { println!("Debugging") }
}
#[cfg(not(feature = "debugging"))]
macro_rules! log {
() => { }
}
fn main() {
log!();
}
Here, you can use Cargo's "features" to provide a compile-time argument that switches the implementation of debugging.
However, there's no requirement to use macros in this case:
#[cfg(feature = "debugging")]
fn log() { println!("Debugging") }
#[cfg(not(feature = "debugging"))]
fn log() {}
fn main() {
log();
}
I'd trust pretty heavily in the optimizer to produce the same code in this case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With