Section 18:
 18.1 What is "const correctness"? 18.2 How is "const correctness" related to ordinary type safety? 18.3 Should I try to get things const correct "sooner" or "later"? 18.4 What does "Fred const* p" mean? 18.5 Difference between "Fred const* p", "Fred* const p" and "Fred const* const p"? 18.6 What does "Fred const& x" mean? 18.7 Does "Fred& const x" make any sense? 18.8 What does "const X& x" mean? 18.9 What does "const X* x" mean? 18.1 What is a "const member function"? 18.11 Using return-by-reference in a const member function? 18.12 What's the deal with "const-overloading"? 18.13 How a const member function can make an "invisible" change to a data member? 18.14 Does const_cast mean lost optimization opportunities? 18.15 Binding a pointer-to-const to a non-const object? 18.16 Does "Fred const* p" mean that *p can't change? 18.17 Errors trying to convert Foo** → Foo const**?
[18.17] Why am I getting an error converting a Foo** Foo const**?

Because converting Foo** Foo const** would be invalid and dangerous.

C++ allows the (safe) conversion Foo* Foo const*, but gives an error if you try to implicitly convert Foo** Foo const**.

The rationale for why that error is a good thing is given below. But first, here is the most common solution: simply change Foo const** to Foo const* const*:

```class Foo { /* ... */ };

void f(Foo const** p);
void g(Foo const* const* p);

int main()
{
Foo** p = /*...*/;
...
f(p);  // ERROR: it's illegal and immoral to convert Foo** to Foo const**
g(p);  // OK: it's legal and moral to convert Foo** to Foo const* const*
...
}
```
The reason the conversion from Foo** Foo const** is dangerous is that it would let you silently and accidentally modify a const Foo object without a cast:
```class Foo {
public:
void modify();  // make some modification to the this object
};

int main()
{
const Foo x;
Foo* p;
Foo const** q = &p;  // q now points to p; this is (fortunately!) an error
*q = &x;             // p now points to x
p->modify();         // Ouch: modifies a const Foo!!
...
}
```
If the q = &p line were legal, q would be pointing at p. The next line, *q = &x, changes p itself (since *q is p) to point at x. That would be a bad thing, since we would have lost the const qualifier: p is a Foo* but x is a const Foo. The p->modify() line exploits p's ability to modify its referent, which is the real problem, since we ended up modifying a const Foo.

By way of analogy, if you hide a criminal under a lawful disguise, he can then exploit the trust given to that disguise. That's bad.

Thankfully C++ prevents you from doing this: the line q = &p is flagged by the C++ compiler as a compile-time error. Reminder: please do not pointer-cast your way around that compile-time error message. Just Say No!

(Note: there is a conceptual similarity between this and the prohibition against converting Derived** to Base**.)