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 intint const *
- pointer to const intint * const
- const pointer to intint 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 intint ** const
- a const pointer to a pointer to an intint * const *
- a pointer to a const pointer to an intint const **
- a pointer to a pointer to a const intint * 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.
- You can change the data it is pointing to but cannot point to a different memory location.
- 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:
const char*
is a pointer to a constantchar
char const*
is a pointer to a constantchar
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) int
eger.
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 writeint const *
, - for a "constant pointer to constant
int
", I writeint 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 const
ness 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
Get Current Time in Milliseconds, or Hh:Mm:Ss:Mmm Format
How to Measure Memory Usage from Inside a C++ Program
How to Best Silence a Warning About Unused Variables
When to Use Virtual Destructors
How to Detect Unsigned Integer Overflow
What Are the Main Purposes of Using Std::Forward and Which Problems It Solves
When Should You Use a Class VS a Struct in C++
Thou Shalt Not Inherit from Std::Vector
Opencv C++/Obj-C: Detecting a Sheet of Paper/Square Detection
Function With Same Name But Different Signature in Derived Class
Fastest Way to Check If a File Exists Using Standard C++/C++11,14,17/C
Difference Between Function Template and Template Function
Forcing the Qt Gui to Update Before Entering a Separate Function
Difference Between Const Int*, Const Int * Const, and Int Const *