Gotcha #31: Misunderstanding Pointer-to-Const Conversion
First, let's get some terminology straight. A "const pointer" is a pointer that is constant. It doesn't imply that what the pointer refers to is constant. True, the C++ standard library has a concept of const_iterator, which is a non-constant iterator into a sequence of constant elements, but that is a symptom of design-by-committee or some similar disease.
const char *pci; // pointer to const
char * const cpi = 0; // const pointer
char const *pci2; // pointer to const, see Gotcha #18
const char * const cpci = 0; // const pointer to const
char *ip; // pointer
The standard permits conversions that "increase constness." For example, we can copy a pointer to non-const to a pointer to const. This allows us to, among other things, pass a pointer to non-constant character to the standard strcmp or strlen functions, even though they're declared to accept pointers to constant character. Intuitively, we understand that in allowing a pointer to const to refer to non-constant data, we're not violating any constraint implied by the data's declaration. We also understand the reverse conversion is invalid, because it would grant greater permission than the declaration of the data specifies:
size_t strlen( const char * );
// . . .
int i = strlen( cpi ); // OK . . .
pci = ip; // OK . . .
ip = pci; // error!
Note that the language rules take the conservative point of view: it may actually be "OK," in the sense of not dumping core immediately, to modify the data referred to by a pointer to const if those data actually aren't const, or if they are const but the platform doesn't allocate const data in a read-only area of memory. However, the use of const is typically a statement of design intent as well as a physical property. The language can be seen to enforce the intent of the designer.
|