Jeremy

constexpr

This value/function can be evaluate at compile time.

If the compiler has enough information, it does the computation during compilation, not at runtime.

This gives you:

  • Better performance (no runtime cost)

  • Stronger correctness checks

  • Ability to use results in places that require compile-time constants

constexpr variables

constexpr int size = 10;
int arr[size]; // OK: size is known at compile time
  • Comparison
const int x = 10; // maybe compile-time
constexpr int y = 10; // guaranteed compile-time

constexpr functions

A constexpr function:

  • Can run at compile time if arguments are known
  • Otherwise runs normally at runtime
constexpr int square(int x) {
  return x * x;
}

constexpr int a = square(5); // compile-time
int b = square(7); // runtime
// Same function, two different evaluation times.

Rules or constexpr functions

  • C++11 (strict)

    • Single return statement
    • No loops, no branches
  • C++14+ (relaxed)

    • if, for, while and local variables
constexpr int factorial(int n) {
  int result = 1;
  for (int i = 1; i <= n; ++i) {
    return *= i;
  }
  return result;
}

constexpr int f = factorial(5); // 120

constexpr constructors & classes

struct Point {
  int x, y;
  constexpr Point(int a, int b) : x(a), y(b) {}
};

constexpr Point p (1, 2); // created at compile time

Useful for:

  • Geometry
  • Configuration tables
  • Embedded systems (flash storage)

When compile-time evaluation Fails

int x;
constexpr int y = x; // error: x not know at compile time
constexpr int foo(int x) {
  return x + rand(); // not allowed
}

Compile-time code must be:

  • Deterministic
  • No, I/O
  • No system calls
  • No heap allocation (until C++20 limited support)