Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. C++ Dictionary
  3. const / constexpr

const / constexpr

The const qualifier in C++ marks variables, arguments, and member functions as immutable. Since C++11, constexpr allows declaring constants and functions whose values are determined at compile time. Using constexpr eliminates runtime overhead and enables the values to be used as template arguments and array sizes.

Syntax

// --- const ---
const int MAX_HP = 9000;          // constant variable (may be initialized at runtime)
const double PI = 3.14159265;

// Passes argument without copy and prevents modification
void printName(const std::string& name);

// const member function: the function does not modify the object's state
class Pilot {
    int syncRate;
public:
    int getSyncRate() const { return syncRate; }
};

// --- constexpr ---
constexpr int MAX_ANGELS = 17;       // compile-time constant
constexpr double G = 9.80665;

// constexpr function: evaluated at compile time when arguments are constant expressions
constexpr int square(int n) {
    return n * n;
}

constexpr int area = square(5);      // becomes 25 at compile time
int arr[square(3)];                  // usable as array size (= arr[9])

// --- Difference from const ---
// const    : can be a runtime constant (initializer need not be a constant expression)
// constexpr: must be a compile-time constant (initializer must be a constant expression)
int runtimeValue = 42;
const int c1 = runtimeValue;         // OK (initialized at runtime)
// constexpr int c2 = runtimeValue;  // error (not a constant expression)

Syntax Reference

Syntax / ConceptDescription
const variableDeclares an immutable variable. The initializer may be a runtime value or a function return value.
const argument (by reference)Receiving as const T& passes without copying and prevents modification. A common idiom for efficiently passing large objects.
const member functionAdding const at the end of a member function signature makes it a read-only function callable on const objects or pointers.
constexpr variableDeclares a compile-time constant. Usable as template arguments, array sizes, and switch case labels.
constexpr functionEvaluated at compile time when arguments are constant expressions. Also callable at runtime with runtime values, in which case it behaves as a normal function.
constexpr constructorAdding constexpr to a constructor allows the object itself to be a compile-time constant (C++11 and later).

Sample Code

eva_const.cpp
#include <iostream>
#include <string>

// constexpr compile-time constants
constexpr int MAX_SYNC_RATE   = 400;
constexpr int EVA_UNIT_COUNT  = 3;
constexpr int ANGEL_COUNT     = 17;

// constexpr function: determines awakening state at compile time
constexpr bool isAwakened(int syncRate) {
    return syncRate >= 400;
}

constexpr int square(int n) {
    return n * n;
}

// Struct with a constexpr constructor
struct EvaSpec {
    int unitNumber;
    int designSyncLimit;

    constexpr EvaSpec(int unit, int limit)
        : unitNumber(unit), designSyncLimit(limit) {}

    constexpr bool isOverLimit(int syncRate) const {
        return syncRate > designSyncLimit;
    }
};

constexpr EvaSpec UNIT_01(1, 400);
constexpr EvaSpec UNIT_02(2, 400);
constexpr EvaSpec UNIT_00(0, 400);

// const reference argument: receives string without copying
void printPilot(const std::string& pilotName, int syncRate) {
    std::cout << "Pilot: " << pilotName
              << "  Sync rate: " << syncRate << "%" << std::endl;
    if (isAwakened(syncRate)) {
        std::cout << "  *** AWAKENED ***" << std::endl;
    }
}

// Class with const and non-const member functions
class Pilot {
    std::string name;
    int         syncRate;

public:
    Pilot(const std::string& name, int syncRate)
        : name(name), syncRate(syncRate) {}

    // const member functions: do not modify the object
    std::string getName()     const { return name; }
    int  getSyncRate()        const { return syncRate; }
    void showStatus()         const {
        std::cout << "Pilot: " << name
                  << "  Sync: " << syncRate << "%" << std::endl;
    }

    // non-const member function: modifies the object
    void updateSyncRate(int newRate) {
        syncRate = (newRate < MAX_SYNC_RATE) ? newRate : MAX_SYNC_RATE;
    }
};

int main() {
    std::cout << "=== Constants ===" << std::endl;
    std::cout << "Max sync rate : " << MAX_SYNC_RATE   << "%" << std::endl;
    std::cout << "Eva unit count: " << EVA_UNIT_COUNT  << std::endl;
    std::cout << "Angel count   : " << ANGEL_COUNT     << std::endl << std::endl;

    // constexpr function evaluated at compile time
    constexpr int logBufferSize = square(16);   // 256 at compile time
    std::cout << "Log buffer size: " << logBufferSize << " bytes" << std::endl;

    int runtimeSync = 400;
    std::cout << "Awakened (runtime): " << (isAwakened(runtimeSync) ? "true" : "false")
              << std::endl << std::endl;

    std::cout << "=== Unit specs ===" << std::endl;
    std::cout << "Unit-01 design sync limit: " << UNIT_01.designSyncLimit << "%" << std::endl;
    std::cout << "Unit-01 sync 410% exceeds limit: "
              << (UNIT_01.isOverLimit(410) ? "yes" : "no") << std::endl << std::endl;

    std::cout << "=== Pilot sync rates ===" << std::endl;
    const Pilot shinji("Ikari Shinji",  400);   // const object
    Pilot       rei   ("Ayanami Rei",   360);
    Pilot       asuka ("Asuka Langley", 300);
    Pilot       kaworu("Nagisa Kaworu", 999);
    Pilot       misato("Katsuragi Misato", 0);

    shinji.showStatus();   // const member function callable on const object
    // shinji.updateSyncRate(350);  // compile error: non-const function on const object

    rei.showStatus();
    rei.updateSyncRate(375);
    std::cout << "  -> Updated sync: " << rei.getSyncRate() << "%" << std::endl;

    asuka.showStatus();
    kaworu.showStatus();
    misato.showStatus();
    std::cout << std::endl;

    std::cout << "=== Awakening check ===" << std::endl;
    printPilot(shinji.getName(), shinji.getSyncRate());
    printPilot(kaworu.getName(), kaworu.getSyncRate());
    printPilot(asuka.getName(),  asuka.getSyncRate());

    return 0;
}
g++ -std=c++14 eva_const.cpp -o eva_const
./eva_const
=== Constants ===
Max sync rate : 400%
Eva unit count: 3
Angel count   : 17

Log buffer size: 256 bytes
Awakened (runtime): true

=== Unit specs ===
Unit-01 design sync limit: 400%
Unit-01 sync 410% exceeds limit: yes

=== Pilot sync rates ===
Pilot: Ikari Shinji  Sync: 400%
Pilot: Ayanami Rei  Sync: 360%
  -> Updated sync: 375%
Pilot: Asuka Langley  Sync: 300%
Pilot: Nagisa Kaworu  Sync: 400%
Pilot: Katsuragi Misato  Sync: 0%

=== Awakening check ===
Pilot: Ikari Shinji  Sync rate: 400%
  *** AWAKENED ***
Pilot: Nagisa Kaworu  Sync rate: 400%
  *** AWAKENED ***
Pilot: Asuka Langley  Sync rate: 300%

Common Mistake 1: Initializing a constexpr variable with a runtime value

The initializer of a constexpr variable must be a constant expression. Using a runtime value causes a compile error.

// NG: runtime value cannot initialize constexpr
int runtimeSync = 400;
constexpr int limit = runtimeSync;  // error: 'runtimeSync' is not a constant expression

OK: Use const for values determined at runtime.

// OK: const accepts runtime values
int runtimeSync = 400;
const int limit = runtimeSync;  // OK

Common Mistake 2: Modifying a member variable inside a const member function

A const member function is read-only; attempting to modify a member variable inside one causes a compile error.

// NG: modifying a member variable in a const member function
class Pilot {
    int syncRate;
public:
    void boost() const {
        syncRate += 10;  // error: assignment of member in read-only object
    }
};

OK: Do not mark a function const if it modifies member variables.

// OK: functions that modify state must not be const
class Pilot {
    int syncRate;
public:
    void boost() {            // no const -> modification allowed
        syncRate += 10;
    }
    int getSyncRate() const { return syncRate; }  // read-only -> const
};

Overview

const is a qualifier that forbids modification of variables, arguments, and member functions. Receiving arguments as const T& avoids copying while preventing modification — a common idiom when passing strings and large objects to functions. A const at the end of a member function signature means "this method does not change the object's state" and allows the function to be called on const objects. constexpr (C++11 and later) guarantees that a value is determined at compile time, making it usable wherever an integer constant expression is required — template arguments, array sizes, and switch case labels. A constexpr function is evaluated at compile time when its arguments are constant expressions; it also works as a normal function when called with runtime values. The key difference from const is that a constexpr initializer must be a constant expression, otherwise the code does not compile. Since C++14, constexpr functions may contain multiple statements and local variables, enabling more complex compile-time computations.

If you find any errors or copyright issues, please .