What's the point of const pointers?

I'm not talking about pointers to const values, but const pointers themselves.

I'm learning C and C++ beyond the very basic stuff and just until today I realized that pointers are passed by value to functions, which makes sense. This means that inside a function I can make the copied pointer point to some other value without affecting the original pointer from the caller.

So what's the point of having a function header that says:

void foo(int* const ptr);

Inside such a function you cannot make ptr point to something else because it's const and you don't want it to be modified, but a function like this:

void foo(int* ptr);

Does the work just as well! because the pointer is copied anyways and the pointer in the caller is not affected even if you modify the copy. So what's the advantage of const?


const is a tool which you should use in pursuit of a very important C++ concept:

Find bugs at compile-time, rather than run-time, by getting the compiler to enforce what you mean.

Even though it doesn't change the functionality, adding const generates a compiler error when you're doing things you didn't mean to do. Imagine the following typo:

void foo(int* ptr)
{
    ptr = 0;// oops, I meant *ptr = 0
}

If you use int* const, this would generate a compiler error because you're changing the value to ptr. Adding restrictions via syntax is a good thing in general. Just don't take it too far -- the example you gave is a case where most people don't bother using const.


I make a point of using only const arguments because this enables more compiler checks: if I accidentally re-assign an argument value inside the function, the compiler bites me.

I rarely reuse variables, it’s cleaner to create new variables to hold new values, so essentially all my variable declarations are const (except for some cases such as loop variables where const would prevent the code from working).

Note that this makes only sense in the definition of a function. It doesn’t belong in the declaration, which is what the user sees. And the user doesn’t care whether I use const for parameters inside the function.

Example:

// foo.h
int frob(int x);
// foo.cpp
int frob(int const x) {
   MyConfigType const config = get_the_config();
   return x * config.scaling;
}

Notice how both the argument and the local variable are const. Neither is necessary but with functions that are even slightly larger, this has repeatedly saved me from making mistakes.


Your question touches on something more general: Should function arguments be const?

The constness of value arguments (like your pointer) is an implementation detail, and it does not form part of the function declaration. This means that your function is always this:

void foo(T);

It is entirely up to the implementer of the function whether she wants to use the functions-scope argument variable in a mutable or in a constant way:

// implementation 1
void foo(T const x)
{
  // I won't touch x
  T y = x;
  // ...
}

// implementation 2
void foo(T x)
{
  // l33t coding skillz
  while (*x-- = zap()) { /* ... */ }
}

So, follow the simple rule to never put const in the declaration (header), and put it in the definition (implementation) if you don't want or need to modify the variable.


The top level const qualifier is discarded in declarations, so the declarations in the question declare exactly the same function. On the other hand, in the definition (implementation) the compiler will verify that if you mark the pointer as const, it is not modified inside the body of the function.