可以检查一个值是Rust中的编译时常量吗?

时间:2016-08-27 06:33:00

标签: macros rust

在某些情况下,内联函数或宏将扩展为大量代码。但是,当与常量一起使用时,可以优化掉死枝。

我可以在代码中添加注释:

// foo arg is always a constant, dead branches will be removed

但我宁愿添加某种静态断言来确保始终如此。

Rust中是否有办法检查值是否为编译时常量?

像GCC的__builtin_constant_p

2 个答案:

答案 0 :(得分:3)

如果值或表达式的类型是固定的并且事先已知,则可以定义局部常量并使用值或表达式对其进行初始化。如果您不以其他方式使用常量,请在其名称前加下划线,以禁止编译器警告有关未使用的常量。但这仅适用于宏。

const _ASSERT_COMPILE_TIME_CONSTANT: i32 = $arg;

夜间编译器还支持定义" const函数",即可以在编译器需要可在编译时计算的表达式的上下文中使用的函数。这些函数的主体受到限制,但是在编译时不需要计算的const函数的调用站点可以传递在编译时无法作为参数求值的表达式,因此定义const函数不会; t提供您要求的保证。

如果无法在宏中指定值或表达式的类型,则我们不能省略它,因为const要求指定类型。但是,我们可以使用泛型const函数在const初始值设定项中返回固定类型!

// at the beginning of the crate
#![feature(const_fn)]

// in the macro's body
const fn _swallow<T>(_x: T) { () }
const _ASSERT_COMPILE_TIME_CONSTANT: () = _swallow($arg);

答案 1 :(得分:0)

要添加到@Francis答案,这是一个可用于确保常量值的宏。

php -v

请注意,需要额外的括号,因此多次使用不会失败:

macro_rules! ensure_const_expr {
    ($value:expr, $t:ty) => {
        {
            const _IGNORE: $t = $value;
        }
    }
}


// in a functions body
ensure_const_expr!(some_variable, i32);