What's the Point of Const Pointers

What's the point of const pointers?

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.

Constant pointer vs Pointer to constant

const int* ptr; 

declares ptr a pointer to const int type. You can modify ptr itself but the object pointed to by ptr shall not be modified.

const int a = 10;
const int* ptr = &a;
*ptr = 5; // wrong
ptr++; // right

While

int * const ptr;  

declares ptr a const pointer to int type. You are not allowed to modify ptr but the object pointed to by ptr can be modified.

int a = 10;
int *const ptr = &a;
*ptr = 5; // right
ptr++; // wrong

Generally I would prefer the declaration like this which make it easy to read and understand (read from right to left):

int const  *ptr; // ptr is a pointer to constant int 
int *const ptr; // ptr is a constant pointer to int

What use are const pointers (as opposed to pointers to const objects)?

When you're designing C programs for embedded systems, or special purpose programs that need to refer to the same memory (multi-processor applications sharing memory) then you need constant pointers.

For instance, I have a 32 bit MIPs processor that has a little LCD attached to it. I have to write my LCD data to a specific port in memory, which then gets sent to the LCD controller.

I could #define that number, but then I also have to cast it as a pointer, and the C compiler doesn't have as many options when I do that.

Further, I might need it to be volatile, which can also be cast, but it's easier and clearer to use the syntax provided - a const pointer to a volatile memory location.

For PC programs, an example would be: If you design DOS VGA games (there are tutorials online which are fun to go through to learn basic low level graphics) then you need to write to the VGA memory, which might be referenced as an offset from a const pointer.

-Adam

What is the difference between const int*, const int * const, and int const *?

Read it backwards (as driven by Clockwise/Spiral Rule):

  • int* - pointer to int
  • int const * - pointer to const int
  • int * const - const pointer to int
  • int const * const - const pointer to const int

Now the first const can be on either side of the type so:

  • const int * == int const *
  • const int * const == int const * const

If you want to go really crazy you can do things like this:

  • int ** - pointer to pointer to int
  • int ** const - a const pointer to a pointer to an int
  • int * const * - a pointer to a const pointer to an int
  • int const ** - a pointer to a pointer to a const int
  • int * const * const - a const pointer to a const pointer to an int
  • ...

And to make sure we are clear on the meaning of const:

int a = 5, b = 10, c = 15;

const int* foo; // pointer to constant int.
foo = &a; // assignment to where foo points to.

/* dummy statement*/
*foo = 6; // the value of a can´t get changed through the pointer.

foo = &b; // the pointer foo can be changed.

int *const bar = &c; // constant pointer to int
// note, you actually need to set the pointer
// here because you can't change it later ;)

*bar = 16; // the value of c can be changed through the pointer.

/* dummy statement*/
bar = &a; // not possible because bar is a constant pointer.

foo is a variable pointer to a constant integer. This lets you change what you point to but not the value that you point to. Most often this is seen with C-style strings where you have a pointer to a const char. You may change which string you point to but you can't change the content of these strings. This is important when the string itself is in the data segment of a program and shouldn't be changed.

bar is a constant or fixed pointer to a value that can be changed. This is like a reference without the extra syntactic sugar. Because of this fact, usually you would use a reference where you would use a T* const pointer unless you need to allow NULL pointers.

What is the purpose of a constant pointer in c++?

Constant pointers are useful for two principal reasons.

  1. this is a const pointer in a const member function.

  2. A const pointer can also be set to nullptr.

My first point is somewhat circular, this could have been a reference type or a const reference type, but references arrived late into the C++ standard, and any changes would have been breaking.

Pointing to a const pointer (or a pointer to a const)

Your first rewrite did not work, because you tried to assign an address of a constant pointer to a pointer-to-pointer where the final "pointee" (i.e. the int) is constant, rather than the pointer in the middle. In other words, if C allowed this

int *const p1 = &v1;
const int **p2 = &p1; // Not allowed

it should allow this:

*p2 = &v2; // This would be legal.

However, this would have modified the pointer p1, which is allegedly constant.

Here is what you need to change for the first rewrite to work:

int *const p1 = &v1;
int * const *p2 = &p1;

Note how const is moved from before the declaration to between the asterisks. Now you are making a pointer to a constant pointer to int.

Your second rewrite fails because it drops const-ness altogether. To fix it, put const back at the beginning of the declaration:

const int *p1 = &v1;
const int **p2 = &p1;

constant pointer vs pointer on a constant value

char * const a;

means that the pointer is constant and immutable but the pointed data is not.

You could use const_cast(in C++) or c-style cast to cast away the constness in this case as data itself is not constant.

const char * a;

means that the pointed data cannot be written to using the pointer a.
Using a const_cast(C++) or c-style cast to cast away the constness in this case causes Undefined Behavior.

Meaning of const pointers as function parameters

ptr = malloc(1023);
This wound't affect the passed value (outside this function, of
course).

To sum up. Indeed that way original pointer would not be affected (it would still point to same object because ptr is copy of the original pointer), but you can still make that pointer point to a different object inside myAnotherFunction and change value of that object through that pointer. e.g. in myAnotherFunction you could do:

ptr = &y;
*ptr = 9;

Whereas in the first case when you have a constant pointer, you can't assign a new address to it, but you can still change the value of object to which it points using dereferencing. A constant pointer means you can't assign a new address to it, pointer to a constant object means you can't change value of object to which it points, but you can assign new address to the pointer.

Const reference vs pointer to const

In the first example, you have a const pointer to a non-const int. This is, because const applies to the thing left of it, except there is nothing at the left side, then it applies to the right thing. Therefore, it's OK to increment the value, but it would be forbidden to increment the pointer (increment without dereferencing). In the second example, you try to increment a const reference, which is not allowed.



Related Topics



Leave a reply



Submit