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 intint const *
- pointer to const intint * const
- const pointer to intint 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 intint ** const
- a const pointer to a pointer to an intint * const *
- a pointer to a const pointer to an intint const **
- a pointer to a pointer to a const intint * 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.
this
is aconst
pointer in aconst
member function.A
const
pointer can also be set tonullptr
.
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
How to Compare Two Character Strings Statically at Compile Time
Both Asterisk and Ampersand in a Parameter
Can Different Gcc Dialects Be Linked Together
Best Bignum Library to Solve Project Euler Problems in C++
Why Is the Copy Constructor Called When We Pass an Object as an Argument by Value to a Method
Erasing Vector::End from Vector
Specialization of 'Template<Class _Tp> Struct Std::Less' in Different Namespace
Overload Resolution with Std::Function
Speed Difference Between If-Else and Ternary Operator in C...
Best Practices for Recovering from a Segmentation Fault
Why Is the Order of Evaluation for Function Parameters Unspecified in C++
Qdialog Exec() and Getting Result Value
How to Save Two Camera's Data But Not Influence Their Picture-Acquire Speed
Std::Async Won't Spawn a New Thread When Return Value Is Not Stored
Sorting a Vector of Objects by a Property of the Object
Why Use #Ifndef Class_H and #Define Class_H in .H File But Not in .Cpp