const & constexpr Basics

Some values should never change: a tax rate, the number of squares on a chessboard, pi. Marking them const tells the compiler to reject any accidental reassignment, and constexpr goes further by computing values at compile time. "Const-correctness" — using const everywhere you can — is one of the habits that separates solid C++ from buggy C++. This lesson makes it second nature.

Learn const & constexpr Basics in our free C++ course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick recall.

Part of the free C++ course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

Think of const as writing a value in permanent ink instead of pencil — you can read it forever, but you can't erase and rewrite it. constexpr is stronger still: it's like a value engraved into the building's cornerstone before the doors even open — fixed at construction time (compile time), so it can be used as part of the structure itself, such as deciding how many rooms (array slots) to build. Both protect you: if you (or a teammate) ever try to change something that was meant to be fixed, the compiler stops you immediately instead of letting a subtle bug slip through.

Rule of thumb: use const by default for anything you don't intend to change; promote to constexpr when the value is a fixed compile-time constant.

1. const: Read-Only Values

Add const before a type and the variable becomes read-only: you must initialize it on the spot, and any later attempt to reassign it is a compile error . This is a feature, not a restriction — it documents intent ("this never changes") and lets the compiler catch accidental writes. By convention, constants are named in UPPER_SNAKE_CASE .

2. constexpr: Compile-Time Constants

constexpr is a promise that a value can be computed at compile time . That unlocks uses where C++ requires a compile-time constant — most notably the size of a fixed array or a . Every constexpr is implicitly const , but it adds the stronger guarantee of compile-time evaluation.

Your turn. Choose the right keyword for each constant — one needs to size an array (so it must be compile-time):

These lines use a constexpr size to build and fill an array. Put them in order:

Open main (C), declare the constexpr size first (B), use it to size the array (A), fill it (D), print data[3] = 3 (E), then return 0; (F) and close (G). N must be a compile-time constant declared before it sizes the array.

3. const References in Parameters

A huge practical use of const is in function parameters. Passing a large object by value copies it; passing by const& hands over a reference (no copy) while promising the function won't modify it. This pattern — const std::string& , const std::vector<T>& — is everywhere in good C++ code: fast and safe.

4. const Member Functions

A member function with const after its parameter list promises not to modify the object it's called on. Getters are the classic example. The payoff: a const object may only call const member functions, so marking your read-only methods const lets them work on constants and documents that they don't mutate state.

A constexpr function is one the compiler can evaluate at compile time when its arguments are themselves constant. The same function still works at run time when given runtime values — you write it once and get both:

Computing values at compile time means zero runtime cost and lets results be used where the language demands a constant. In C++20, consteval forces compile-time evaluation, and constinit guarantees compile-time initialization of globals.

Predict the output (or whether it compiles) before revealing the answer.

No — LIMIT is const , so LIMIT = 10; is an error: "assignment of read-only variable".

In standard C++, int arr[n]; with a non-const n is not allowed (variable-length arrays aren't standard). int brr[m]; with constexpr m is fine — it's a compile-time constant.

Yes — prints 7 — get() is a const member function, so a const object may call it.

Put a constexpr constant and const-correct functions together to compute a circle's area and circumference.

Practice quiz

What does 'const' do to a variable?

  • Makes it global
  • Forces compile-time evaluation
  • Marks it read-only so it cannot be reassigned after initialization
  • Makes it faster

Answer: Marks it read-only so it cannot be reassigned after initialization. const is read-only once set; any attempt to reassign it is a compile error.

What is the key difference between const and constexpr?

  • constexpr requires a value computable at compile time; const may be computed at run time
  • No difference
  • const is compile-time, constexpr is run-time
  • constexpr can be reassigned

Answer: constexpr requires a value computable at compile time; const may be computed at run time. Both can't be reassigned, but constexpr guarantees compile-time evaluation; const only guarantees read-only.

Which can be used as the size of a fixed-size array?

  • Any const
  • Any runtime int
  • Only literals
  • A constexpr value (or a const that is itself a compile-time constant)

Answer: A constexpr value (or a const that is itself a compile-time constant). Array sizes require a compile-time constant; constexpr guarantees this.

Why pass a large object by const reference (const T&)?

  • To copy it safely
  • To avoid copying while promising not to modify it
  • To make it mutable
  • To force compile-time evaluation

Answer: To avoid copying while promising not to modify it. const& gives the speed of passing by reference (no copy) and the safety of read-only access.

What does marking a member function 'const' (after its parameter list) promise?

  • It will not modify the object it is called on
  • It returns a const value
  • It is evaluated at compile time
  • It is private

Answer: It will not modify the object it is called on. A const member function promises not to mutate the object, so const objects may call it.

A const object can call which member functions?

  • Any member function
  • Only static functions
  • Only const member functions
  • None

Answer: Only const member functions. A const object may only call const member functions, which is why getters should be marked const.

Does 'const int LIMIT = 5; LIMIT = 10;' compile?

  • Yes
  • No — 'assignment of read-only variable'
  • Only with -std=c++20
  • Only if LIMIT is global

Answer: No — 'assignment of read-only variable'. Reassigning a const is a compile error.

Can a single constexpr function be called at run time too?

  • No, never
  • Only if marked inline
  • Only with consteval
  • Yes — it runs at compile time when its arguments are constant, and at run time otherwise

Answer: Yes — it runs at compile time when its arguments are constant, and at run time otherwise. A constexpr function works in both modes depending on whether its arguments are compile-time constants.

Why does 'constexpr int x = readInput();' fail to compile?

  • readInput is private
  • The initializer must be a constant expression, but a runtime value isn't known at compile time
  • constexpr needs a double
  • x must be const

Answer: The initializer must be a constant expression, but a runtime value isn't known at compile time. constexpr demands a compile-time-known initializer; use plain const for a runtime value.

Every constexpr variable is also:

  • static
  • inline
  • const
  • volatile

Answer: const. constexpr implies const and adds the stronger guarantee of compile-time evaluation.