Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equivalent of constexpr from C++?

Tags:

rust

See this code:

fn main() {
    let something_const = 42;
    fn multiply(nbr: i32) -> i32 {
        nbr * something_const
    }
    println!("{}", multiply(1));
}

rustc outputs that

error[E0434]: can't capture dynamic environment in a fn item; use the || { ... } closure form instead
  --> main.rs:19:15
   |
19 |         nbr * something_const
   |               ^^^^^^^^^^^^^^^

But something_const is not dynamic, because it is known at compile time.

Is it an equivalent in Rust of the C++ constexpr mechanism?

like image 333
Boiethios Avatar asked Dec 27 '16 13:12

Boiethios


People also ask

Does constexpr exist in C?

The keyword constexpr was introduced in C++11 and improved in C++14. It means constant expression. Like const , it can be applied to variables: A compiler error is raised when any code attempts to modify the value. Unlike const , constexpr can also be applied to functions and class constructors.

When to use #define vs constexpr?

#define (also called a 'macro') is simply a text substitution that happens during preprocessor phase, before the actual compiler. And it is obviously not typed. constexpr on the other hand, happens during actual parsing. And it is indeed typed.

What is constexpr static?

Static specifies the lifetime of the variable. A static constexpr variable has to be set at compilation, because its lifetime is the the whole program. Without the static keyword, the compiler isn't bound to set the value at compilation, and could decide to set it later.

How do I declare constexpr?

To be constexpr, a function must be rather simple: just a return-statement computing a value. A constexpr function can be used for non-constant arguments, but when that is done the result is not a constant expression.


1 Answers

constexpr in C++ can be used in 2 different situations:

  • to qualify a constant, and denote that this constant must be available at compile-time
  • to qualify a function, and denote that this function must be available for compile-time evaluation

Rust supports both, albeit in a limited fashion:

  • you can use const to declare a constant, instead of let, to declare that it is truly constant
  • you can use const to qualify a function, to declare that it can be evaluated at compile-time. Not all functions can be made const yet.

In your situation, you want the first usage:

fn main() {
    const something_const: i32 = 42;

    fn multiply(nbr: i32) -> i32 {
        nbr * something_const
    }

    println!("{}", multiply(1));
}

Note that unlike with let, it is mandatory to annotate the constant with its type.

Also, the compiler will complain about the naming; constants use ALL_CAPS.

like image 52
Matthieu M. Avatar answered Oct 14 '22 12:10

Matthieu M.