Const int pointer error

I am learning about persistent pointers and I tried to do this

#include<iostream>
using namespace std ;
int main(){
    int a = 10 ; 
    const int *cp  = &a ;               // my constant pointer variable
    cout<<"\nAddress stored in cp = "<<cp ;
    ++cp;
    cout<<"\nAddress stored in cp = "<<cp   ;
}

      

It incremented the address that was stored in cp

But according to what I have understood so far, one should not ++cp

give an error as it is a persistent pointer that always points to the same address and this address cannot be changed.

But when I replaced

const int *cp = &a ;

from int *const cp = &a ;

It gives me this enter image description here

Forgive my ignorance, but don't they mean the same thing?

+3


source to share


5 answers


When you execute int *const cp = &a;

it means an integer pointer to the constant cp, so cp cannot change. However, in your previous version const int *cp

means a constant int pointer to cp, so a value where the cp points cannot change, but the pointer itself can.

Usually people like to read this from right to left:



const int *cp

cp is a pointer to a constant int, so the integer cannot change.

int *const cp = &a;

cp is a constant pointer to int, so the pointer cannot change.

+2


source


const int *cp  = &a ; 

      

The content of the address it points cp

to is read-only, but the pointer is cp

not

So,



*cp = value ; //Illegal
++cp ; // Legal

      


int *const cp = &a ;

      

The pointer is read-only, but the content of the address it points to cp

is not

So,



*cp = value ; //Legal
++cp ; // Illegal

      


Besides,

const int *const cp  = &a ;

      

Both pointers, as well as the address of the address they point to cp

, are read-only

*cp = value ; //Illegal
++cp ; // Illegal

      

For a simple right-to-left readable ad

+2


source


const int *cp1  = &a ; // pointer is variable, pointed to is constant
int *const cp2  = &a ; // pointer is constant, pointed to is variable
const int *const cp3  = &a ; // pointer is constant, pointed to is constant

      

Thus,

cp1++; // possible
*cp1++; // not possible
cp2++; // not possible
*cp2++; // possible
cp3++; // not possible
*cp3++; // not possible

      

+1


source


If it helps at all (and it probably doesn't), the following synonyms, taking advantage of the language, which allows the type to const

be exposed to appear on the immediate left or right side of the type, but before any additional qualifiers (such as pointers or references):

const int * p; // does NOT require initialization
int const * q; // same as above

      

Both declare pointers to constant data int

and are used interchangeably in syntax.

Whereas this:

int * const p = &a; // requires initialization.

      

declares a persistent pointer to data int

; not a pointer to persistent data int

.

Continuing this (effectively combining both of them), we get:

const int * const p = &a;
int const * const p = &a;

      

These are synonyms. Both declare a constant pointer to constant int data. Neither the pointer nor what it points to is modifiable, and both require initialization.


Shamelessly torn chart

The following was shamelessly ripped off of myself (well, not much shame), from a slightly related question . Hopefully this will help explain even more the differences in what happens when you position const

and *

in different places of the ad:

Single-Indirect :

char *p;               // p is mutable, *p is mutable
const char *p;         // p is mutable, *p is const
char const *p;         // same as above.
char *const p;         // p is const, *p is mutable, must be initialized.
char const *const p;   // p is const, *p is const, must be initialized.

      

Double Indirection :

char **p;        // ptr-to-ptr-to-char
                 // p, *p, and **p are ALL mutable

const char **p;  // ptr-to-ptr-to-const-char
                 // p and *p are mutable, **p is const

char const **p;  // same as above

char *const *p;  // ptr-to-const-ptr-to-char
                 // p is mutable, *p is const, **p is mutable.

char **const p;  // const-ptr-to-ptr-to-char
                 // p is const, *p is mutable, **p is mutable.
                 // must be initialized.

const char **const p;  // const-ptr-to-ptr-to-const-char
                       // p is const, *p is mutable, **p is const.
                       // must be initialized.

char const **const p;  // same as above

char const *const *p;  // ptr-to-const-ptr-to-const-char
                       // p is mutable, *p is const, **p is const.

const char *const *p;  // same as above.

char *const *const p;  // const-ptr-to-const-ptr-to-char
                       // p is const, *p is const, **p is mutable.
                       // must be initialized.

      

And my personal favorite:

char const *const *const p;   // const-ptr-to-const-ptr-to-const-char
                              // everything is const.
                              // must be initialized.

const char *const *const p;   // same as above

      

+1


source


This is one of the reasons I always recommend placing to the const

right of int

not to the left. How in:

int const *cp;

      

and not:

const int *cp;

      

This has the advantage that the element created const

is the one to the right of the keyword const

and it's to the left.

In the above example, * cp (i.e. the content of cp) is const and the type is int. If you write

int * const cp = &foo;

      

and apply the same rules, cp

there is const

, and the element const

is of type int *

. When there are multiple levels of indirection, using this rule makes it much easier to understand what's going on.

int const ** cpp1;
int * const *cpp2;
int ** const cpp3 = &bar;
int const ** const cpp4 = &xyz;

      

This latter is a const

pointer to a mutable pointer to const int

. And one element const

is of type int

and the other is of type int **

. It's trivial to understand if you never put a word to the const

left of int

.

0


source







All Articles