Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pointer-to-const can point to non-const object - language design or technical reason?



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

    //Example 2
    double pie = 3.14;         //non-const object
    const double *cptr = &pie; //non-pointer-to-const to non-const object
    double *ptr = &pie;        //non-pointer-to-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, non-pointer-to-const would treat const object as non-const object but compiler will throw error at compile time.

Am I missing something here?

like image 367
kypronite Avatar asked Oct 25 '12 04:10

kypronite


2 Answers

Declaring a const says, "The value of this variable should not change."

Declaring a pointer to a const says, "I have no intention of changing the variable I am pointing to".


Question 1: why do you get an error when a pointer to a variable is assigned the address of a const?

// Example 1
const int i = 0;
int * p = &i;        /* Error */

Answer: Because the first line says, "please guarantee that the value of i doesn't change", but in the second line the compiler can no longer make that guarantee - the type information on the pointer p is not strict enough to tell the compiler not to allow changes to the pointed-to value i.


Question 2: why don't you get an error when a pointer to a const is assigned the address of a variable?

// Example 2
int j = 0;
const int * q = &j;  /* No error */

Answer: Because a pointer to a const says, "please guarantee that the value of j does not change via q". Note that the via q is important because the pointer to const declaration doesn't mean that the value pointed to must be a constant, only that whoever is using the pointer can't use the pointer to change the value.

like image 66
Brian L Avatar answered Sep 20 '22 17:09

Brian L


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.

like image 26
jogojapan Avatar answered Sep 22 '22 17:09

jogojapan