Tasdik Rahman
Tasdik Rahman

Reputation: 2330

const int pointer error

I am learning about constant pointers and I was trying 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 which was stored in cp But according to what I have understood until now, shouldn't ++cp give an error as it is a constant pointer that always points to the same address and this address cannot be modified.

But when I replaced

const int *cp = &a ; with int *const cp = &a ;

It gives me this enter image description here

Forgive my ignorance but, aren't they suppose to mean the same thing ?

Upvotes: 3

Views: 968

Answers (5)

dgnuff
dgnuff

Reputation: 3557

This is one of the reasons I always recommend placing the const on the right of the int not the left. As in:

int const *cp;

and not:

const int *cp;

That has the advantage that the item that is made const is what's on the right of the const keyword, and it's type is on the left.

In the above, *cp (i.e. the contents of cp) is const, and it's type is int. If you write

int * const cp = &foo;

and apply the same rules, cp is const and the const item has type int *. When there are multiple levels of indirection, using this rule makes it far easier to understand what's happening.

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

That last one is a const pointer to a mutable pointer to a const int. And one const item has type int while the other has type int **. Trivial to understand, as long as you never place the word const on the left of the int.

Upvotes: 0

WhozCraig
WhozCraig

Reputation: 66194

If it helps at all (and it probably doesn't), the following are synonymous, taking advantage of a language nicety that allows an opening type to have const appear on the immediate left or right of the type, but before any additional qualifiers (like pointers or references):

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

Both declare pointers to constant int data, and are interchangeable in syntax.

Whereas this:

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

declares a constant pointer to int data; not a pointer to constant int data.

Extending this further (actually merging them both), we get:

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

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


Shamelessly Ripped Off Chart

The following was shamelessly ripped off from.. myself (ok, not that much shame), from a slightly related question. I hope it helps further explain the differences in what happens when you position const and * in different places of a declaration:

Single-Indirection:

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

Upvotes: 1

P0W
P0W

Reputation: 47784

const int *cp  = &a ; 

Content of address pointed by cp is read-only, however pointer cp is not

So,

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

int *const cp = &a ;

Pointer is read-only, however content of address pointed by cp is not

So,

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

Also,

const int *const cp  = &a ;

Both pointer as well as content of address pointed by cp are read-only

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

For simple declaration read from right to left

Upvotes: 2

Dr. Debasish Jana
Dr. Debasish Jana

Reputation: 7118

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

Upvotes: 1

Javi
Javi

Reputation: 3610

When you are doing int *const cp = &a; it means a integer pointer to a constant cp, so cp cannot change. However, in your previous version const int *cp means a constant int pointer to cp, so the value where 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 int constant, so the integer number cannot change.

int *const cp = &a; cp is a constant pointer to an int, so the pointer cannot change.

Upvotes: 2

Related Questions