Question
constexpr vs const in C++: What’s the Difference and When to Use Each
Question
What is the difference between constexpr and const in C++?
When can only one of them be used? When can both be used, and how should you decide which one to choose?
Short Answer
By the end of this page, you will understand that const means a value cannot be modified after initialization, while constexpr means a value or function can be evaluated at compile time when possible. You will learn when they overlap, when they differ, and how to choose the right one in practical C++ code.
Concept
const and constexpr are related, but they are not the same thing.
const
const means read-only after initialization. Once a const variable has been given a value, your program cannot change it.
const int x = 10;
// x = 20; // error
This does not automatically mean the value is known at compile time.
int n = getValue();
const int x = n; // valid if n is available at runtime
Here, x is still read-only, but its value depends on runtime data.
constexpr
constexpr means the value is intended to be a constant expression, which means the compiler can compute it at compile time.
constexpr int x = 10;
A constexpr variable must be initialized with a compile-time constant expression.
Mental Model
Think of const and constexpr like labels on a box:
constmeans "this box is sealed after you fill it".constexprmeans "this box must be filled before the factory ships it".
With const, you can fill the box later at runtime, then seal it.
With constexpr, the box must already be filled during compilation.
So:
constfocuses on immutabilityconstexprfocuses on compile-time availability
Syntax and Examples
Basic syntax
const int a = 10;
constexpr int b = 10;
Both are read-only, but b is also guaranteed to be a constant expression.
Example 1: const with a runtime value
#include <iostream>
int getAge() {
return 25;
}
int main() {
const int age = getAge();
std::cout << age << '\n';
}
age cannot be changed after initialization, but it is not necessarily known at compile time because it comes from a function call that runs at runtime.
Example 2: constexpr with a compile-time value
constexpr int daysInWeek = ;
hoursInDay = ;
hoursInWeek = daysInWeek * hoursInDay;
Step by Step Execution
Consider this example:
#include <iostream>
constexpr int add(int a, int b) {
return a + b;
}
int main() {
const int x = 10;
constexpr int y = 20;
constexpr int z = add(2, 3);
std::cout << x << ' ' << y << ' ' << z << '\n';
}
Step by step
1. The compiler sees constexpr int add(int a, int b)
This tells the compiler that add can be evaluated at compile time if its arguments are constant expressions.
2. const int x = 10;
xis read-only- it cannot be reassigned
- this line does not primarily promise compile-time use; it promises immutability
Real World Use Cases
When const is useful
Read-only configuration loaded at runtime
const std::string filePath = readConfigFilePath();
The path is not known during compilation, but you still want to prevent accidental modification.
Function parameters that should not change
void printMessage(const std::string& message);
This tells readers and the compiler that the function will not modify message.
Protecting member functions and objects
class User {
public:
std::string getName() const;
};
Here, const is part of API design and correctness.
When constexpr is useful
Compile-time constants
pi = ;
Real Codebase Usage
In real projects, developers usually choose based on intent.
Common pattern: use const for runtime immutability
const auto userId = request.getUserId();
const auto timeout = config.readTimeout();
These values come from runtime data, so constexpr is not possible.
Common pattern: use constexpr for true constants
constexpr int maxRetries = 3;
constexpr char apiVersion[] = "v1";
These are fixed program constants and may be used in compile-time contexts.
Guard clauses and validation
void connect(int port) {
constexpr int minPort = 1;
constexpr int maxPort = 65535;
if (port < minPort || port > maxPort) {
std::();
}
}
Common Mistakes
1. Thinking const always means compile-time constant
Broken assumption:
int getValue();
const int x = getValue();
x is read-only, but its value is not known at compile time.
How to avoid it
Ask:
- Is this just immutable?
- Or does the compiler need to know it during compilation?
2. Using constexpr with a runtime value
Broken code:
int n = 10;
constexpr int x = n; // error
Why it fails
n is not a constant expression.
Fix
constexpr int n = 10;
constexpr int x = n;
Comparisons
const vs constexpr
| Feature | const | constexpr |
|---|---|---|
| Prevents modification after initialization | Yes | Yes |
| Requires compile-time value | No | Yes |
| Can use runtime initialization | Yes | No |
| Can be used where constant expression is required | Not guaranteed | Yes |
| Best meaning | Read-only | Compile-time constant |
Variables: when to choose
| Situation | Preferred choice |
|---|
Cheat Sheet
Quick rules
const= read-only after initializationconstexpr= compile-time constant- Every
constexprvariable is effectivelyconst - Not every
constvariable isconstexpr
Syntax
const int a = 10;
constexpr int b = 10;
constexpr int square(int x) {
return x * x;
}
Use const when
- the value is decided at runtime
- you want to prevent accidental changes
- you are working with parameters, references, pointers, or member functions
Use constexpr when
- the value is known during compilation
- the value may be used in constant-expression contexts
- you want compile-time computation
Common examples
FAQ
Is constexpr always better than const?
No. Use constexpr when a compile-time constant is intended. Use const when you only need a read-only value, especially if it comes from runtime data.
Is every constexpr variable also const?
Yes, a constexpr variable is immutable and acts like a constant.
Can a const variable be initialized at runtime?
Yes. That is one of the main differences. const does not require compile-time initialization.
Can a constexpr function be called at runtime?
Yes. If the arguments are not constant expressions, the function can still execute at runtime.
Should I use constexpr for all fixed numeric constants?
Usually yes, if they are truly compile-time constants and that meaning is useful in the code.
Why not just use #define for constants?
Because constexpr and const are type-safe, scoped, and checked by the compiler.
Mini Project
Description
Build a small C++ program that demonstrates the difference between runtime read-only values and compile-time constants. This project is useful because many real programs contain both kinds of data: configuration read at runtime and fixed limits or formulas known at compile time.
Goal
Create a program that uses const for runtime values and constexpr for compile-time values, then prints results showing the difference.
Requirements
[ "Create a constexpr function that performs a simple calculation.", "Declare at least one constexpr variable initialized with a compile-time value.", "Read or simulate a runtime value and store it in a const variable.", "Print both the compile-time and runtime-based results.", "Use clear variable names that show why each keyword was chosen." ]
Keep learning
Related questions
Basic Rules and Idioms for Operator Overloading in C++
Learn the core rules, syntax, and common idioms for operator overloading in C++, including member vs non-member operators.
C++ Base Class Constructor Rules Explained
Learn how C++ base class constructors are called from derived classes, including order, syntax, defaults, and common mistakes.
C++ Casts Explained: C-Style Cast vs static_cast vs dynamic_cast
Learn the difference between C-style casts, static_cast, and dynamic_cast in C++ with clear examples, safety rules, and real usage tips.