带有条件编译的宏



在调试模式下(cfg!(debug_assertions)),我有一个结构体Foo有2个字段{a:i16,only_in_debug:i16}在释放模式下,结构体有一个字段{a:i16}

sum函数在调试模式下为only_in_debug字段增加一个数字,但在发布模式下不做任何事情(该字段缺失)。

我写了一个宏,但在发布模式下不工作:

macro_rules! sum {
($a:expr,$b:expr)=>{
if cfg!(debug_assertions) {
$a+=$b;
}
}
}

结构在调试模式

#[cfg(debug_assertions)]
#[derive(Debug)]
pub struct Foo {
pub a: i16,
pub only_in_debug: i16,
}
#[cfg(debug_assertions)]
impl Default for Foo {
fn default() -> Foo {
Foo {
a: 0,
only_in_debug: 0,
}
}
}

struct in release mode


#[cfg(not(debug_assertions))]
pub struct Foo {
pub a: i16,
}
#[cfg(not(debug_assertions))]
impl Default for Foo {
fn default() -> Foo {
Foo {
a: 0
}
}
}

主:


fn main() {
let mut foo = Foo::default();
sum!(foo.only_in_debug, 10);
println!("{:?}", foo); // (**)
}

在调试模式下运行,行(**)打印:Foo { a: 0, only_in_debug: 10 }

但在释放模式下显示^^^^^^^^^^^^^ unknown field

在C语言中,它使用预处理器宏

#ifdef NDEBUG
#define sum(a, b)
#else
#define sum(a, b) (a+=(b))
#endif

cfg!宏将在编译时求值为truefalse,但if中的代码将始终被编译,因此必须进行类型检查。如果您希望在cfg计算结果为false时不编译代码,则需要将#[cfg()]属性附加到表达式:

macro_rules! sum {
($a:expr, $b:expr)=>{
#[cfg(debug_assertions)] {
$a += $b;
}
}
}

的例子:

struct Foo {
x: i32,
}
fn main() {
let foo = Foo { x: 1 };
// This fails to compile.
// if cfg!(target_pointer_width = "8") {
//     foo.y;
// }
#[cfg(target_pointer_width = "8")]
{
foo.y;
}
}
游乐场

最新更新