Skip to content
Theory · References and Pointers · lesson 5 of 8

const T* and T* const

The variable a in this program is declared without const, yet the compiler does not let the pointer p change it:

C++
int main() {
    int a = 1;
    int b = 2;
    const int* p = &a;
    *p = 5;  // ✗
    p = &b;
    return *p;
}
TEXT
error: read-only variable is not assignable

The error is only on the line *p = 5;, while the line p = &b; compiles. What const forbids in a pointer declaration depends on where it stands.

Pointer to const

const int* p is a pointer to const. The value can be read through it but not changed. It may also point to a variable without const: the ban covers only writing through p, and a = 5; still works. p itself is an ordinary variable, so it can be pointed elsewhere, as in the line p = &b;.

A function that only reads numbers through a pointer declares its parameter as const int* data. Such a declaration promises that the function will not change the numbers. An accidental write such as data[0] = 0; in the body fails with the same error as *p = 5;. This way the compiler makes sure that the function does not change the caller's numbers.

Const pointer

When const comes after the *, the pointer itself becomes constant. int* const q is a const pointer: it cannot be pointed elsewhere, so it is initialized right away. The value, though, can be changed through q. const int* const r forbids both.

C++
#include <iostream>

int main() {
    int a = 1;
    int b = 2;
    const int* p = &a;
    p = &b;
    int* const q = &a;
    *q = 5;
    std::cout << *p << ' ' << a << '\n';  // 2 5
}

What decides is where const stands relative to the *. To the left of the asterisk it applies to the value, and to the right it applies to the pointer itself. That is why int const* p means the same as const int* p.

A declaration is easiest to read from right to left, starting at the name. int* const q reads "q is a const pointer to int". const int* p reads "p is a pointer to int that is const".

Common mistake

The address of a const variable is stored in a plain pointer:

C++
int main() {
    const int limit = 10;
    int* p = &limit;  // ✗
    return *p;
}
TEXT
error: cannot initialize a variable of type 'int *' with an rvalue of type 'const int *'

Through an int*, the value of limit could be changed, so the compiler rejects this initialization. Declare the pointer as const int* p = &limit;.