I have a program like below and expect that:
with function void myFunc1 ( const int *x)
==> I cannot change the value of at the memory location that x
points to, but can change the memory location that x
points to.
with function void myFunc2 ( int const *x)
==> I cannot change the location that x
points to as it is a const pointer. But I could change the value at the memory location that x
points to.
However, upon compiling the code, I don't see the difference between const int *x
vs int const *x
:
*x=8
in both function return error. I didn't expect error from myFunc2
because it is a const
pointer, not a pointer to a const
value.myFunc1
, I expected to see value 5 after myFunc1
is close.Could the experts here explain my 2 unexpected results above ? Here is my code:
#include "stdio.h"
int a = 5; // declared a global,
void myFunc1 ( const int *x) { // const parameter: pointer to a const int value.
// *x= 8; // error: assignment of read-only location ‘* x’ ==> cannot change the value at the location pointed by pointer. This is expected
printf("%d \n ", *x);
x = &a; // can change where the pointer point to.
// a is global and is not loss after closing myFunc2
printf("value in myFunc1: %d \n ", *x);
}
void myFunc2 ( int const *x) { // const parameter: const pointer, cannot change the address that x points to.
// *x= 8; // error: assignment of read-only location ‘* x’
printf("%d \n ", *x);
x = &a; // no compiling error here. This is not expected.
printf("value in myFunc2: %d \n ", *x);
}
int main() {
int *y;
int z = 6;
y = &z;
printf("value before myFunc1: %d \n", *y);
myFunc1(y);
printf("value after myFunc1: %d \n", *y); // expect to print 5. Result: print 6.
printf("value before myFunc2: %d \n", *y);
myFunc2(y);
printf("value after myFunc2: %d \n", *y); // expect to print 8 if the line *x=8 could be compiled . Result: print 6.
return 1;
}
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.
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,
int
", I write int const *
,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.