I can't figure out how to tell C that I want a pointer that will not move. It will always point to the same array. That said, the array members are not constant, but the array itself is global and so, it is at a fixed position.
So, when I code this:
#include <stdio.h>
int v[2]={0, 1};
const int *cpv=v;
int main(void)
{
v[1]=2; printf("%d\n", v[1]);
*(cpv+1)=3; printf("%d\n", v[1]);
cpv[1]=4; printf("%d\n", v[1]);
}
And get this errors:
constp.c: In function ‘main’:
constp.c:9: error: assignment of read-only location '*(cpv + 4u)'
constp.c:10: error: assignment of read-only location '*(cpv + 4u)'
I understand that the compiler thinks I need a const int v[2]
to use with a const int *iv
. How do I get a constant pointer to do the job?
If you see the error message, I'm not even moving the pointer (like pv++
). I'm just dereferencing it dislocated some bytes.
If I do this:
int *pv=cpv;
*(pv+1)=5; printf("%d\n", v[1]);
printf("%p == %p !?\n", cpv, pv);
I get this warning, but it works:
constp.c:9: warning: assignment discards qualifiers from pointer target type
pointer# ./constp
5
0x601020 == 0x601020 !?
Thanks, Beco.
Pointers kind of "read backwards":
In this case, "
p
" is a (variable) "pointer" to a "const int
". Literally, read that backwards, with the '*
' meaning "pointer": "Pointer ... to int const".Curiously, the following is the same thing:
Reading backwards, it says, "pointer ... to const int" (the same thing).
So, if you want your pointer to be "constant" (not variable), you need to read-backwards and do just that:
Now, "
p
" is a constant pointer to a non-constant integer. Not to belabor, but reading backwards that's, "const pointer ... to int".Using the "same thing" example above, we can now have a constant pointer to a constant integer (the following are the same):
You should read them backwards, and they both say the same thing, "contant pointer ... to constant int".
You are using a pointer to const, not a const pointer.
should turn into:
Move the
const
qualifier:Explanation: in the C declaration rules, this is read from right to left starting at the identifier: "
cpv
is a constant pointer toint
". Your version would be read "cpv
is a pointer toint
constant".Note that
cpv+1
will still get you a pointer to theint
after*cpv
; making a pointerconst
only prevents++
,--
,+=
and-=
on it.Having said that, why do you need the pointer at all? The compiler will be able to do a better job if you would access the variable v directly. If you go via a pointer, the generated code have to read the pointer from memory each time you access the array.