【问题标题】:Will the Rust compiler exclude branches dependent on constants from the compiled executable?Rust 编译器会从编译的可执行文件中排除依赖于常量的分支吗?
【发布时间】:2021-08-04 10:01:47
【问题描述】:

我有代码:

const DEBUG_MODE: bool = false;

fn main() {
    if DEBUG_MODE {
        println!("In debug mode!");
    }
    println!("Normal code");
}

Rust 编译器是否会删除分支,使其与以下内容相同:

fn main() {
    println!("Normal code");
}

编译出来的程序集输出会有什么不同吗?

DEBUG_MODEtrue 的情况下,它是内联分支还是实际进行汇编检查?

如果我们有这样的函数:

fn debug_fn() {
    if !DEBUG_MODE {
        return;
    }
    println!("Some debug function");
}

如果DEBUG_MODEfalse,对它的所有调用会被优化掉还是仍然会有某种形式的开销?

【问题讨论】:

标签: rust


【解决方案1】:

是的,它会的。作为a simpler example

const DEBUG_MODE: bool = false;

pub fn example() {
    if DEBUG_MODE {
        call_me();
    }
    call_me();
}

#[inline(never)]
fn call_me() {
    println!("called");
}

在发布模式下编译时,Rust 1.54 为 example 生成此 x86_64 程序集,而 DEBUG_MODEtrue

playground::example:
    jmp playground::call_me

DEBUG_MODEfalse

playground::example:
    pushq   %rax
    callq   playground::call_me
    popq    %rax
    jmp playground::call_me

如 cmets 中所述,为 conditional compilation 使用 cfg 属性更为惯用,因为它可以在编译器的较早级别进行处理。这意味着您可能存在某些类型的无效代码。例如:

pub fn example() {
    #[cfg(some_debug_mode)]
    {
        oops_i_never_defined_this_function();
        call_me();
    }
    call_me();
}

不常用但仍然有价值的是cfg! 宏。这将解析为 truefalse 并且您依赖与原始案例相同的死代码消除:

pub fn example() {
    if cfg!(some_debug_mode) {
        call_me();
    }
    call_me();
}

另见:

【讨论】:

猜你喜欢
  • 2019-02-03
  • 2012-04-28
  • 1970-01-01
  • 2012-08-20
  • 2019-08-23
  • 1970-01-01
  • 1970-01-01
  • 2019-06-22
相关资源
最近更新 更多