const int*, int * const, const int * const: Bloody Pointless Breakdown

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why does this topic drive even experienced C++ developers crazy?

\n\n

If you've ever opened someone else's C++ code and seen something like const int * const data, you've probably felt the urge to close the editor and go drink tea. This strange syntax with const scattered on both sides of the asterisk is a real stumbling block. The question “What is the difference between const int*, const int * const, and int * const?” on Stack Overflow has gathered hundreds of thousands of views. And this is no coincidence.

\n\n

Understanding these constructs is not just a pedant's whim. It is the key to writing safe, self-documenting code and, importantly, to passing job interviews. Today, we will sort out this confusion once and for all, using a simple rule that always works.

\n\n

The Three Pillars: What are we comparing?

\n\n

In C++, pointers and constness can be combined in four ways (three of which are the most popular). Let's denote them:

\n\n
    \n
  • Option 1: const int* ptr (or int const* ptr — they are the same).
  • \n
  • Option 2: int * const ptr.
  • \n
  • Option 3: const int * const ptr (a combination of the first two).
  • \n
\n\n

The key idea: const always refers to what is to its left. If there is nothing to its left, it refers to what is to its right. It sounds simple, but in practice, this rule saves the day.

\n\n

Option 1: const int* ptr (Pointer to a constant integer)

\n\n

Read from right to left: “ptr is a pointer to an integer that is constant”.

\n\n

What does this mean in practice?

\n
    \n
  • You cannot change the value of the variable that ptr points to through this pointer.
  • \n
  • You can change the pointer itself (make it point to a different variable).
  • \n
\n\n
#include <iostream>\n\nint main() {\n    int a = 10;\n    int b = 20;\n\n    const int* ptr = &a;  // ptr — pointer to const int\n\n    // *ptr = 15; // COMPILATION ERROR! Cannot change value through const int*\n    std::cout << "*ptr = " << *ptr << std::endl; // Outputs 10\n\n    ptr = &b; // OK! Changing the pointer itself\n    std::cout << "*ptr = " << *ptr << std::endl; // Outputs 20\n\n    return 0;\n}
\n\n

This type is often used to pass data to a function when you want to guarantee that the function will not corrupt the original data. For example, the string void print(const int* data) is a “read-only” promise.

\n\n

Option 2: int * const ptr (Constant pointer to an integer)

\n\n

Read from right to left: “ptr is a constant pointer to an integer”.

\n\n

Here, it's the opposite:

\n
    \n
  • You can change the value of the variable that ptr points to.
  • \n
  • You cannot change the pointer itself (it must always point to the same memory location).
  • \n
\n\n
#include <iostream>\n\nint main() {\n    int a = 10;\n    int b = 20;\n\n    int * const ptr = &a; // ptr — constant pointer to int\n\n    *ptr = 15; // OK! Changing the value through the pointer\n    std::cout << "*ptr = " << *ptr << std::endl; // Outputs 15\n\n    // ptr = &b; // COMPILATION ERROR! Cannot change the pointer itself\n\n    return 0;\n}
\n\n

Think of int * const as a “bound” pointer. It is often used for working with hardware registers or in cases where a pointer to a buffer should not “escape” to another location.

\n\n

Option 3: const int * const ptr (Constant pointer to a constant integer)

\n\n

Read from right to left: “ptr is a constant pointer to an integer that is constant”.

Blogs

Book Recommendations