Search code examples
c++pointerslanguage-designconst-correctness

Why can a pointer-to-const point to a non-const object?


//Example 1
const double pie = 3.14;   // const object
const double *cptr = &pie; // pointer-to-const to const object
double *ptr = &pie;        // ERROR - pointer-to-non-const to const

//Example 2
double pie = 3.14;         // non-const object
const double *cptr = &pie; // pointer-to-const to non-const object
double *ptr = &pie;        // pointer-to-non-const to non-const object

Initially I though pointer-to-const to non-const object is allowed because it just mean pointer-to-const won't change non-const object.

But i just read in c++ book that the reason pointer-to-const to non-const object is allowed because there's no way for pointer-to-const pointer to really know whether the object it points to is const, so it treat the object it points as const but by the same logic, pointer-to-non-const would treat const object as non-const object but compiler will throw error at compile time.

Am I missing something here?


Solution

  • A pointer-to-const

    const double *p
    

    treats the object it points to as a constant object, i.e. it won't allow you to change it. As soon as you dereferentiate the pointer

    *p
    

    you are dealing with a constant object. If you try to modify that,

    *p = 1.0;
    

    you will get an error message from the compiler.

    On the other hand, a pointer-to-non-const,

    double *p
    

    treats the object it points to as non-const and therefore allows you to modify its value:

    *p = 1.0;
    

    becomes legal. However, if at any given time you have a constant object

    const double d = 1.0;
    

    you won't be able to create a pointer-to-non-const that points to it:

    double *p = &d;
    

    won't be accepted by the compiler. So yes, the compiler enables a pointer-to-non-const to modify the objects it points to. But it doesn't enable you to create a pointer-to-non-const that points to a constant object. So you won't run into a situation where a pointer-to-non-const can be used to modify a constant object.

    Regarding the question in the title: This is primarily a language design decision. However, the fact that the compiler can rely on certain objects to never change value means that various optimizations are possible. For example, if the same pointer is dereferentiated twice in a function with other code between the two dereferentiations, and if that pointer is a pointer-to-const, the compiler will assume it does not actually have to fetch the value from memory twice, because the value is not allowed to have changed between the first and the second dereferentiation.