c++ c pointers constants c++-faq
Updated Fri, 20 May 2022 22:21:39 GMT

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.


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 cant 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.

Comments (5)

  • +0 – I would like to append a rule of thumb which may help you remember how to discover whether 'const' applies to pointer or to pointed data: split the statement at asterix sign, then, if the const keyword appears in the left part (like in 'const int * foo') - it belongs to pointed data, if it's in the right part ('int * const bar') - it's about the pointer. — Jul 17, 2009 at 17:26  
  • +0 – @Michael: Kudos to Michael for such a simple rule for remembering/understanding const rule. — Feb 11, 2010 at 19:00  
  • +0 – @Jeffrey: read it backwards works well as long as there are no parenthesis. Then, well... use typedefs — May 28, 2013 at 19:53  
  • +0 – +1, though a better summary would be: read pointer declarations backwards, that means, close to @Michael 's statement: stop the normal left-to-right reading at the first asterisk. — Jun 18, 2014 at 09:21  
  • +4 – @gedamial it does, it works fine, but you must assign it at the same time you declare it (because you can't reassign a "const pointer"). const int x = 0; const int *const px = &x; const int *const *const p = &px; works just fine. — Aug 08, 2016 at 23:15  

External Links

External links referenced by this document: