Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to redefine a macro?

Tags:

rust

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?

like image 476
Jouan Avatar asked Jun 11 '15 16:06

Jouan


2 Answers

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.

like image 67
mdup Avatar answered Nov 15 '22 09:11

mdup


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.

like image 31
Shepmaster Avatar answered Nov 15 '22 09:11

Shepmaster