C++ const vs constexpr: What’s the Real Difference?
Both are used in C++ to define constants.
Why This Matters
Modern C++ encourages writing immutable, efficient, and expressive code. Two keywords—const and constexpr—sit at the heart of that effort. They look similar, but understanding their distinct guarantees is crucial for clean compile‑time and run‑time behavior.
High‑Level Comparison
| Feature | const |
constexpr |
|---|---|---|
| Compile‑time constant? | Maybe | Always (or fails to compile) |
| Runtime OK? | Yes | Yes (evaluated at runtime if needed) |
| Array/template usage | Only if truly constant | Guaranteed |
| Functions allowed? | Only qualifiers on member | Full functions evaluable at CT |
1 Declaring Immutable Data
const: Immutable After Construction
const int runtimeConst = std::rand(); // const but NOT a compile‑time constant
When you merely want to prohibit modification—regardless of when the value is known—const is enough.
constexpr: Must Be Known at Compile Time
constexpr int arraySize = 10;
int arr[arraySize]; // Always valid
If the value must participate in contexts that require a constant expression (array bounds, template parameters, switch labels), choose constexpr.
2 Functions and Methods
const Member Functions
class Widget {
public:
int value() const {/*…*/} // promises not to modify *this
};
They protect object state but offer no compile‑time guarantee.
constexpr Functions
constexpr int square(int n) { return n * n; }
static_assert(square(4) == 16, "computed at compile time");
A constexpr function can run during compilation whenever its arguments are constant expressions, yet it still works at run time.
3 Common Pitfalls
// 1. Compiles: runtimeConst is merely const
const int runtimeConst = std::rand();
// 2. Fails: std::rand() is not constexpr
constexpr int fails = std::rand();
Remember: every constexpr variable is implicitly const, but not every const variable is a constant expression.
4 Guidelines for Choosing
- Need guaranteed compile‑time evaluation? Use
constexpr. - Need immutability but value might come from a run‑time calculation? Use
const. - Prefer
constexprif unsure; the compiler will complain if the initializer isn’t a constant expression.
5 Summary Snippet
constexpr int ctVal = 42; // compile‑time
const int rtVal = std::rand(); // run‑time, still immutable
Choosing correctly between const and constexpr unlocks safer, faster, and more expressive C++ code. Default to constexpr for constants you truly want at compile time, and reserve const for values determined during execution.
C/C++ Programming
- Understanding std::transform_reduce in Modern C++
- Implement a Lock Acquire and Release in C++
- Detecting Compile-time vs Runtime in C++: if consteval vs std::is_constant_evaluated()
- C++ Forward References: The Key to Perfect Forwarding
- Understanding dynamic_cast in C++: Safe Downcasting Explained
- C vs C++: Understanding the restrict Keyword and its Role in Optimization
- C++ Lvalue, Rvalue and Rvalue References
- C++ assert vs static_assert
- Why auto_ptr is Deprecated in C++?
- C++ What is the consteval? How is it different to const and constexpr?
- Tutorial on C++ std::move (Transfer Ownership)
- const vs constexpr in C++
- Tutorial on C++ Ranges
- Tutorial on C++ Smart Pointers
- Tutorial on C++ Future, Async and Promise
- The Memory Manager in C/C++: Heap vs Stack
- The String Memory Comparision Function memcmp() in C/C++
- Modern C++ Language Features
- Comparisions of push_back() and emplace_back() in C++ std::vector
- C++ Coding Reference: is_sorted_until() and is_sorted()
- C++ Coding Reference: iota() Setting Incrementing Values to Arrays or Vectors
- C++ Coding Reference: next_permutation() and prev_permutation()
- C++ Coding Reference: count() and count_if()
- C++ Code Reference: std::accumulate() and Examples
- C++ Coding Reference: sort() and stable_sort()
- The Next Permutation Algorithm in C++ std::next_permutation()
–EOF (The Ultimate Computing & Technology Blog) —
Last Post: Tutorial on C++ Ranges
Next Post: Tutorial on C++ std::move (Transfer Ownership)