logo

C++ - const vs constexpr vs consteval vs constinit

TL;DR

  • const:
    • runtime constant.
    • can only be used for non-static member functions, not functions in general.
  • constexpr: Since C++11
    • MAY be evaluated at compile-time, but may be at runtime.
      • A constexpr function can also be called at runtime like a regular function if its arguments are not constant expressions or if the result is not needed in a context that requires a constant expression.
    • can be used for both variables and functions.
  • consteval functions: Since C++20
    • a.k.a. immediate functions;
    • MUST be evaluated at compile-time: always produce a compile-time expression and always visible only at compile-time.
    • consteval can only be applied to the declaration of a function or function template.
  • constinit: Since C++20,
    • asserts that a variable has static initialization (zero initialization or constant initialization).
    • when the declared variable is a reference, constinit is equivalent to constexpr.
    • purpose: to prevent the "static initialization fiasco," where the order of initialization of static variables across translation units is undefined.

More on const and constexpr

All constexpr variables are const, constexpr member functions are NOT implicitly const.

These are equivalent:

  • const char* const
  • constexpr const char*
  • constexpr const char* const

More on consteval and constinit

  • Both introduced in C++20.
  • Both guarantees compile-time evaluations.
  • consteval is for functions and constinit is for static and thread-local variables.