void main()
{
const int * a;
*a = 5;
}
gcc error : assignment of read only location.
so, how to assign to *a, without using another variable? and what could be a use of a declaration like above?
void main()
{
const int * a;
*a = 5;
}
gcc error : assignment of read only location.
so, how to assign to *a, without using another variable? and what could be a use of a declaration like above?
Isnt the point with const
that you cant assign to it? Although, I dont recall in the case of const pointers if its the value it points to that cant be altered, or the adress of the pointer. Or both. My guess is that neither can be changed.
It can also be a general warning (or error, depending on compiler settings) that you try to write to uninitialized memory.
Correct would be (I assume):
void main()
{
const int* a = new int(5);
}
The problem is that you've created a pointer, but it doesnt actually point to anything, so when you dereference it (or try to write to its referenced loaction), you get an error.
const int * a;
Read the declaration from right to left.[See note] What do you get? a
is a *
i.e. a pointer to int
i.e. an integer const
i.e. a constant. In short, the variable a
points to an integer whose value you cannot change. At least, not through a
. Whether the pointee really is immutable or not is a different question. But fact remains, you cannot use a
to modify *a
;
const
is a promise you make to yourself: I will never ever try to modify the pointee using a pointer to a const. The compiler only gives you support.
If you really want to write to the pointee, you need a non-const pointer something like:
int *a;
*a = 42; /* this is fine */
And a very nice comment from bortzmeyer: (I thought I'd skip this to keep it simple :)
You can also put the
const
after the*
(as you said, declarations should be read from right to left).
What he means is this:
const int *a;
is no different from
int const *a;
(Remember, the right to left reading rule?) But is very different from:
int * const p;
Read it and we get: p
is a const
(-ant) *
(pointer) to int
(-eger). Translated: once you set p
to point to an integer, you cannot reseat it (i.e. write to it to make it point to another integer -- the point of making p
constant), but you can write to the pointee very much (the pointee is not constant).
Note: For the pedantically inclined here is 'The Rule' from Darron:
"declarations should be read from right to left" is a simplification -- if there are parentheses they should be read from inside out. Unless the parentheses indicate a function call. The real rule is "treat it like an expresion; if I apply these operators I'll eventually get this simple type".
This answer really would have had much less meat but for bortzmeyer and Darron - thank you!
PPS: (I promise this is going to be the last edit. Well, hopefully!)
void main()
is not a standard signature for main in C or C++. Don't use it until you know you or (more importantly) your code will never have to make a voyage to the another universe.
you mean int * const
, not const int *
. In one case the pointer is const, the other the stuff it points to is const. You can also do const int * const
. No harm to read some articles about const_cast, they should cover this ground well.
An example illustrating Ruben Bartelink's excellent explanation:
#include <stdlib.h>
int main()
{
int * const a = malloc(sizeof(int));
if (a == NULL)
return 1;
*a = 3;
free(a);
return 0;
}
Here, a is constant (and therefore must be initialized) but not *a (probably what the OP wanted).
Not answering the "how to assign to *a, without using another variable?" but only "what could be a use of a declaration like above?".
It is a promise not to modify the value pointed to. As discussed in the comment, if you make restrictions on the way you allow yourself to use the construct you can arrive at the conclusion that it is not useful. But if you allow yourself the whole C language then you can find uses. Think of the prototype of strcmp
and such.
Let me put your question into simple English.
The answer: change the promise, at least locally.
int main()
{
const int * a;
*((int *) a) = 5;
}
Hopefully the wording above makes it plain that this is usually a bad idea.