What is the difference between const int*, const int * const, and int const *?
I always mess up how to use const int*
, const int * const
, and int const *
correctly. Is there a set of rules defining what you can and cannot do?
I want to know all the do's and all don'ts in terms of assignments, passing to the functions, etc.
Solution 1:
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.
Solution 2:
For those who don't know about Clockwise/Spiral Rule: Start from the name of the variable, move clockwisely (in this case, move backward) to the next pointer or type. Repeat until expression ends.
Here is a demo:
Solution 3:
I think everything is answered here already, but I just want to add that you should beware of typedef
s! They're NOT just text replacements.
For example:
typedef char *ASTRING;
const ASTRING astring;
The type of astring
is char * const
, not const char *
. This is one reason I always tend to put const
to the right of the type, and never at the start.