Fundamentals 8 min read

When to Use const vs constexpr in C++? A Practical Guide

This article explains the differences between C++ const and constexpr, using a kettle analogy, detailed code examples, and practical guidelines to help developers choose the right keyword for compile‑time or runtime constants, improve performance, and write safer code.

Liangxu Linux
Liangxu Linux
Liangxu Linux
When to Use const vs constexpr in C++? A Practical Guide

From a kettle story to const vs constexpr

Imagine two kettles: an old stove‑top kettle that only provides hot water after boiling (like const) and an electric kettle that always has hot water ready (like constexpr). Both seem similar, but their behavior differs significantly.

const: I promise not to change, but I don't guarantee early knowledge

const

means a value cannot be modified after initialization. The compiler may determine the value at compile time, but it is not required to do so. Example:

const int MAX_PLAYERS = 10; // compile‑time known
MAX_PLAYERS = 11; // error: cannot modify const
const

can be initialized with values known only at runtime:

// Compile‑time known const
const int MAX_PLAYERS = 10; // compiler knows it's 10

// Runtime‑only known const
int GetMaxPlayers() { return 10; } // could read from config
const int RUNTIME_MAX_PLAYERS = GetMaxPlayers(); // value decided at runtime

The key point is that const does not guarantee compile‑time evaluation; it only guarantees immutability.

constexpr: I not only stay constant, I also guarantee compile‑time knowledge

constexpr

(introduced in C++11) explicitly tells the compiler that the value must be known at compile time. Example:

constexpr int MAX_PLAYERS = 10; // compile‑time constant
constexpr int TOTAL_PLAYERS = MAX_PLAYERS * 2; // also compile‑time (20)

If you try to initialize a constexpr with a runtime value, compilation fails:

int GetMaxPlayers() { return 10; }
constexpr int MAX_PLAYERS = GetMaxPlayers(); // error: not a constant expression

When to use which? Practical guide

Use const when

The value is only known at runtime (e.g., user input, file data).

Defining pointer variables where either the pointed‑to data or the pointer itself should be immutable.

const int user_age = getUserInputAge();
const std::string message = loadMessageFromFile();
const int* p = &value; // pointer to const data
int* const p2 = &value; // const pointer

Use constexpr when

The constant can be determined at compile time (e.g., mathematical constants).

You need compile‑time evaluation for array sizes, template parameters, or other compile‑time calculations.

Functions whose results are required at compile time.

constexpr double PI = 3.14159265358979;
constexpr int DAYS_IN_WEEK = 7;
constexpr int SECONDS_PER_DAY = 24 * 60 * 60;
constexpr int square(int n) { return n * n; }
constexpr int result = square(5); // 25 at compile time

Real‑world case: constexpr power

Using constexpr to compute the 10th Fibonacci number at compile time eliminates runtime work:

constexpr int fibonacci(int n) {
    return (n <= 1) ? n : fibonacci(n-1) + fibonacci(n-2);
}
constexpr int fib10 = fibonacci(10); // 55, computed at compile time
int main() {
    std::cout << "Fibonacci(10) = " << fib10 << std::endl;
    return 0;
}

If the same calculation were done with const, it would be performed at runtime, reducing efficiency.

Best‑practice summary

Prefer constexpr whenever possible – it guarantees immutability and enables compile‑time optimization.

Perform simple calculations at compile time – let the compiler do the work.

Use const for function parameters that should not be modified .

Declare class‑wide constants with constexpr – e.g., static constexpr int MAX_PLAYERS = 10;.

One‑sentence distinction

const

promises “I won’t change”, but does not guarantee compile‑time evaluation; constexpr promises both “I won’t change” and “I am known at compile time”.

Final thought question

Consider the following code and identify where const and constexpr are used and why:

constexpr int BUFFER_SIZE = 1024;
void processBuffer(const char* buffer, const int size) {
    constexpr int MAX_SIZE = BUFFER_SIZE * 2;
    const int actualSize = (size > MAX_SIZE) ? MAX_SIZE : size;
    // processing logic...
}

Think about the rationale behind each qualifier.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Runtimebest practicesconstC++Compile-timeConstantsconstexpr
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.