Difference Between Const Int*, Const Int * Const, and Int Const *

What is the difference between const int*, const int * const, and int const *?

Read it backwards (as driven by Clockwise/Spiral Rule):

  • int* - pointer to int
  • int const * - pointer to const int
  • int * const - const pointer to int
  • int const * const - const pointer to const int

Now the first const can be on either side of the type so:

  • const int * == int const *
  • const int * const == int const * const

If you want to go really crazy you can do things like this:

  • int ** - pointer to pointer to int
  • int ** const - a const pointer to a pointer to an int
  • int * const * - a pointer to a const pointer to an int
  • int const ** - a pointer to a pointer to a const int
  • int * const * const - a const pointer to a const pointer to an int
  • ...

And to make sure we are clear on the meaning of const:

int a = 5, b = 10, c = 15;

const int* foo; // pointer to constant int.
foo = &a; // assignment to where foo points to.

/* dummy statement*/
*foo = 6; // the value of a can´t get changed through the pointer.

foo = &b; // the pointer foo can be changed.



int *const bar = &c; // constant pointer to int
// note, you actually need to set the pointer
// here because you can't change it later ;)

*bar = 16; // the value of c can be changed through the pointer.

/* dummy statement*/
bar = &a; // not possible because bar is a constant pointer.

foo is a variable pointer to a constant integer. This lets you change what you point to but not the value that you point to. Most often this is seen with C-style strings where you have a pointer to a const char. You may change which string you point to but you can't change the content of these strings. This is important when the string itself is in the data segment of a program and shouldn't be changed.

bar is a constant or fixed pointer to a value that can be changed. This is like a reference without the extra syntactic sugar. Because of this fact, usually you would use a reference where you would use a T* const pointer unless you need to allow NULL pointers.

Whats the difference between const int const& and const int& in C++?

So is const int const& a reference to a const int?

No, that's a compilation error.

Try compiling something like :

int z = 0;
const int const& a= z;

And you'll see the compiler will yell at you.

You can't duplicate const for the same type. Your premise that const int const* is a constant pointer to a constant int is wrong too.

const int = int const?

They are both valid code and they are both equivalent. For a pointer type though they are both valid code but not equivalent.

Declares 2 ints which are constant:

int const x1 = 3;
const int x2 = 3;

Declares a pointer whose data cannot be changed through the pointer:

const int *p = &someInt;

Declares a pointer who cannot be changed to point to something else:

int * const p = &someInt;

about int const *p and const int *p

With the help of pointer, you can actually do two things.

  1. You can change the data it is pointing to but cannot point to a different memory location.
  2. You can point it to a different memory location but cannot change the data it is pointing to.

Now, when you say, int const* ptr or int const* ptr, it falls under first category. It's same as -

const int num = 5; // Both mean the same.
int const num = 5;

To, actually not able to change to a different location, i.e., pointer to a constant location but be able to modify the data, the semantics should be int* const. Since the content of the pointer is a constant, it should be initialized while declaration.

int num = 5;

int* const ptr; // Wrong
ptr = # // Wrong

int* const ptr = #
*ptr = 100;

However, there is a third kind. Constant pointer to a constant location, which can neither point to a different memory location nor change the data it is pointing to. ( i.e., const int* const )

And now answering the questions, the first two can be compiled because they are not pointing to constant locations. So, they can be modified at later stages too.

const int const *p3 = &i1;
p3 = &i2; // Wrong

In the above snippet, p3 is a constant pointer to a constant location. So, it cannot be modified.

const at the end of a member function says it is not going to change the state of the object. When you say *p = 1;, you are not changing the state of the object. p still points to the same memory location. This is not allowed to do -

int const * Coo2::getP() const   
{
*p = 1; // State of `p` is still not modified.
p = new int ; // Error: Changing the memory location to which p points.
// This is what changing the state of object mean and
// is not allowed because of `const` keyword at the end of function
return this->p;
}

Hope, now you understand why the program compiles :)

'const int' vs. 'int const' as function parameters in C++ and C

const T and T const are identical. With pointer types it becomes more complicated:

  1. const char* is a pointer to a constant char
  2. char const* is a pointer to a constant char
  3. char* const is a constant pointer to a (mutable) char

In other words, (1) and (2) are identical. The only way of making the pointer (rather than the pointee) const is to use a suffix-const.

This is why many people prefer to always put const to the right side of the type (“East const” style): it makes its location relative to the type consistent and easy to remember (it also anecdotally seems to make it easier to teach to beginners).

Is pointer to const int same as const int*

In C++, the const keyword generally applies to the part of the type to its left.

So int const* is a pointer to a constant integer, and int*const is a constant pointer to a non-constant integer.

The type of p in your example is a int const*.

The habit of putting const to the right is known as east const.

Now there is an exception to the "const applies to the left"; when there is nothing to the left, it applies to the right instead. This confusing exception means that const int* is int const*. But using X=int*; const X becomes int*const.

The habit of putting const on the left, and the resulting confusion, is known as west const.

In short, the answer is yes, unless you add aliases.

const pointer and pointer to const value as parameter [duplicate]

I don't see the different between having 2 parameters (const int *x) vs (int const *x):

That's because int const* and const int* are the same thing.

If you want to make the pointer const, you have to put a const on its right, like this: int * const, a constant pointer to (non-constant) integer.



Unrelated (is it?) note on East const

I am one of those in favour of the so called East const, which means I prefer writing the const always on the right of what it applies to. For instance,

  • for a "pointer to constant int", I write int const *,
  • for a "constant pointer to constant int", I write int const * const.

As you see, the sentences in quotes map to the types if you read them right-to-left:

//  1    2   3   4             4       3           2     1
int const * const // constant pointer to constant int

Furthermore, always thinking of const as something that can be put on the right of what it applies to has also other advantages, sometimes in terms of peculiarities of the language that you can discover.

For instance, the following is how I discovered something more about references.

Take the declaration of a function parameter taken by reference to constant: int const& p. If you write it like this and think of it the East const way, it is clear that it declaring a p which is a reference to a constant int, not a constant reference to int.

After all, thinking East const, what would a constant reference to int look like? It'd be int & const, with the const on the right of what we'd like it to apply to, the reference &. However, this syntax is incorrect.

Why is that? Why can't I make a reference constant? Because it always is, as references cannot rebind. The standard simply doesn't let you write something totally redundant as a const applied to a reference.

const int *p vs. int const *p - Is const after the type acceptable?

The most important thing is consistency. If there aren't any coding guidelines for this, then pick one and stick with it. But, if your team already has a de facto standard, don't change it!

That said, I think by far the more common is

const int * i;
int * const j;

because most people write

const int n;

instead of

int const n;

A side note -- an easy way to read pointer constness is to read the declaration starting at the right.

const int * i; // pointer to an int that is const
int * const j; // constant pointer to a (non-const) int
int const * aLessPopularWay; // pointer to a const int


Related Topics



Leave a reply



Submit