Pointers and consts: What's the const?

When you define many things, it's clear what's going on. For example, in the code
   const int MAX = 100;
it's clear what MAX is whether you think of it as an integer constant, or a constant integer.

But many declarations aren't as obvious. If you read them right to left carefully, you won't be fooled. Let's look at a few straightforward ones with their memory pictures:
   int const * p1 = new int(5);
   const int * p2 = new int(6);

      +-+     +---+
   p1 |-|---> | 5 |
      +-+     +---+

      +-+     +---+
   p2 |-|---> | 6 |
      +-+     +---+
You have two pieces of memory, that holding the pointer and that holding the int. So, which one is the const?

Reading from right to left says that p1 is a pointer to a constant integer. That sounds like the int is the constant, not p1, and that's correct. The int, *p1, is the constant. This means you can change p1 with an assignment, but not change *p1.

Ditto for p2. Reading says that p2 is a pointer to an integer constant, so the int is again the const. The memory for p2 can change, but not the memory for *p2.
   // *p1 = 4;           would be an error -- contents are constant
   // *p2 = 4;           would be an error -- contents are constant
   int * p = new int(10);
   int * q = new int(20);
   delete p1;            // don't want any memory leaks
   delete p2;
   p1 = p;
   p2 = q;
Before this code executes, *p1 is 5 and *p2 is 6. After this code executes, *p1 is 10 and *p2 is 20.
      +-+     +----+         +-+     +----+
    p |-|---> | 10 |       q |-|---> | 20 |
      +-+     +----+         +-+     +----+
              ^                      ^
             /                      /
      +-+   /                +-+   / 
   p1 |-|---              p2 |-|--- 
      +-+                    +-+   
Now let's move the asterisk. What's the const now?
   int * const p3 = new int(5);
Reading from right to left says that p3 is a constant pointer to an integer. And we see that p3 is the const. That says we can change the int, *p3, but not the pointer, p3.
   *p3 = 6;
   // p3 = p;            would be an error -- pointer is constant
Can you make both the pointer and the int const?   Yes.   You want a constant pointer to a constant int. Turn that into code:
   int const * const p4 = new int(30);
Now both are constant:
   // p4 = p;            would be an error -- pointer is constant
   // *p4 = 50;          would be an error -- contents are constant
And don't forget to clean up after yourself:
   delete p;
   delete q;
   delete p3;
   delete p4;