This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
const int = int const?
What is the difference between these combination of keywords ?
const int*
int const*
int* const
Is it possible to modify the value of a constant by accessing its address using a pointer ?
const int*
int const*
Both declare an pointer to an constant type int. It means that the pointer can be made to point to(hold) any other address but any attempt to modify the constant integer data type will result in Undefined Behavior.
int* const
Declares an constant pointer to an int type. It means that the pointer cannot be assigned any new address it will always keep pointing to the same address, but the integer it points to can be changed.
Is it possible to modify the value of a constant by accessing its address using a pointer ?
Yes, it is possible but it leads to a ill formed program exhibiting an Undefined Behavior.
In general:
const T === T const
and
const T * === T const *
but
T * const
makes the pointer constant, but not necessarily the contents of T.
const T * const === T const * const
will make both the contents of T and the pointer itself constants.
As for changing the contents of a const: you shouldn't be able to, but the compiler/OS/CPU don't try too hard to stop you, so you get what is colloquially called “undefined behaviour,” which is a nice way of saying “random crashes on some systems”
const int* and int const* are both a pointer to a constant int. This means that the value pointed to can not be changed but the pointer itself can be.
The third example int *const is a constant pointer to an int. This means that the value can be changed but the pointer can not.
Yes you can change the value of the address by using a pointer but doing so is undefined behavior and should be avoided. C++ also offers a const_cast to remove the constness of a variable.
If you have any other questions related to the const keyword you should reference the const correctness section of the C++ FAQ.
The first two are a variable pointer to a const int. The pointer itself can be changed. Without casting away const, the int can't be changed through this pointer. (It may, however, be modifiable through non-const references.)
The last is a const pointer to a variable int. Without casting away const, the pointer itself can't be changed. The int can be changed through the pointer.
This may be helpful. This is another one that talks about breaking it apart so you can see which parts become const in various scenarios.
Const binds to the left.
Unless it is the left most clause then in binds right.
Just read right to left
const int* => (const int)* => "pointer" to "const int"
=> Pointer can change.
=> Can't change the value it points at (the int is const)
int const* => (int const)* => "pointer" to "const int"
=> As above
int* const => int (* const) => "const pointer" to "int"
=> Can't change the pointer (its const) it always points
=> at the same things.
=> You can change the value of the object it points at.
Related
So this is just a duplicate of:
What is the difference between char * const and const char *?
What's the difference between:
char * const
and
const char *
But I still do not get it.
So given the first answer:
The difference is that const char * is a pointer to a const char,
while char * const is a constant pointer to a char.
The first, the value being pointed to can't be changed but the pointer
can be. The second, the value being pointed at can change but the
pointer can't (similar to a reference).
Ok so, I have coded this to:
//exercises
char* barfoo = "variable_test";
const char* my_pointer_to_const_char = barfoo; //"barfoo" can't be changed but the pointer to it, can!
barfoo = "changed!";
std::cout<< barfoo << std::endl;
So according to the answer above, barfoo can't be changed?
I have changed it in my code, and it prints "changed". I don't understand shouldn't it be throwing an error ?
Can you please give me a correct example, because I am doing something wrong clearly.
You are missing two key concepts in your understanding.
A pointer, and the "thing" the pointer is pointing to. They are two separate, discrete "things". The pointer itself. And whatever the pointer is pointing to. That's the first key concept.
The second key concept is that either one, or the other, can be const. Or both can be const. Whatever's const, cannot be changed.
If the pointer itself is const, you can't change the pointer. It will always point to the same "thing", until the pointer goes out of scope and gets destroyed. But, even if the pointer is const, you can use this pointer to modify its "thing" unless the "thing" itself is const.
If the pointer is a pointer to a const "thing" you cannot change the "thing" using this pointer. But you can change the pointer to point to a different const "thing".
Or, even if the pointer is, allegedly, is a pointer to a const "thing", if there's another pointer that's pointing to the same "thing", and the other pointer may not necessarily be a pointer to a const "thing"; it could be a non-const pointer. In that situation, the other pointer can be used to change the same "thing" (because, after all, it is not a pointer to some const thing). And now, even though the first pointer is a pointer to const thing, the const thing it's pointing to has now changed. And this leads to an arcane discussion about aliasing rules that are better left for some other day...
But, back to the subject matter at hand:
char* barfoo = "variable_test";
const char* my_pointer_to_const_char = barfoo; //"barfoo" can't be changed but the pointer to it, can!
barfoo = "changed!";
Here, you changed one of the pointers, itself. You did not change whatever the pointer is pointing to. The literal string "variable_test" is still "there", wherever that "there" is, and the const pointer is still pointing to it. Whatever you do to one pointer, has no effect on the other pointer. They are different "thing"s.
You need to undergo a slight mental shift. You need to clearly separate, in your mind, the pointer itself, from whatever the pointer is pointing to.
We know that pointers store the address values of their operands.
As an example, if char *ptr=a, ptr will store the address of variable a.
And any variable defined as a constant cannot change its value.
If const int a=5, then any statement like a++ is invalid because this will alter the value of a which is prohibited.
Similarly if a pointer ptr points to variable a with declaration const int *ptr=a. Statements like ptr=b will be invalid because ptr cannot point to b as it is a constant pointer pointing to a.
Having understood that, there happen to be two combinations of constants and pointers.
TYPE 1: Pointer to a constant
const int a=5;
int* const ptr=a;
In this case, the variable is a constant whose value cannot be modified.
Suppose the memory address of a is 0x9978. Since, pointer stores address of variable, ptr=0x9978.
Analyse the following statements:-
a=6; //Invalid: Value of a cannot be changed
*ptr=9; //Invalid: *ptr refers to a and will change its value.
int b=t;
ptr=b;//Valid: ptr is not constant and can point anywhere
Hope this concept is clear now.
TYPE 2: Constant pointer
Here the pointer is constant. Once it is pointed to a variable, it cannot point to any other variable. It stores a constant address throughout its life time.
int a=7;
const int* ptr=a;
Here the value of ptr(0x9978) cannot be modified.
See the statements again:-
a=6; //Valid: Value of a can be changed
*ptr=9; //Valid: *ptr refers to a and its value can be altered.
int b=t;
ptr=b;//InValid: ptr is constant and cannot point anywhere else.
Thus, ptr cannot point to any other variable now.
Coming to your question, to understand better, consider char * not as a pointer but as a variable of string type(character buffer)!
char* barfoo = "variable_test"; //barfoo is a string storing 'variable_test'
const char* my_pointer_to_const_char = barfoo;
// This is type 2, constant pointer. Thus, my_pointer_to_const_char cannot
//point to any other variable and will always store the address of barfoo
barfoo = "changed!";
//this is perfectly valid as this statement will alter the value of string
//barfoo. my_pointer_to_const_char will still store the address of barfoo.
If there are still any doubts, feel free to comment:)
This question already has answers here:
What is the difference between const int*, const int * const, and int const *?
(23 answers)
Closed 5 years ago.
int p=10;
const int * ptr=&p; // expression 1
As far as i understood by expression 1 that the data which is pointed by pointer ptr is constant
so if i write
*ptr=10;
which is invalid ,
but if i take another pointer variable like
int * pr=&p;
*pr=19;
cout<<*ptr;
will give me the ouput 19
so now the data pointed by ptr changed
but earlier we have seen that data pointed by ptr is constant
why data is changed by another pointer variable?
const int * ptr=&p; means the data pointed to by ptr is const, but only relative to that pointer.
The pointed-to data is not necessarily really const (=originally declared const) and if it isn't, non-const pointers to it (including the original const-pointer cast to its non-const version) may change it.
If some data is really const, attempts to modify it through an non-const pointer result in undefined behavior.
This is very basic, so my suggestion is to read a basic C++ book.
Despite of that I'll provide the answer.
int p = 10;
It is a statement which declares and defines a variable named p of type int.
The content of this variable can be modified. That's because the variable p is not const.
Obviously the later statement p = 13; is still valid and it assigns a new value to that variable.
Now you have this:
const int* ptr = &p;
You're defining a pointer, named ptr which points to that variable.
Adding the qualifier const to the pointer it simply means that you cannot modify the content of the variable by means of the access of the pointer itself.
In other words, the pointer can be only used (for example) for reading the value of p.
On the other hand:
int* pr = &p;
defines a pointer which is not more const qualified.
Indeed, you can access and modify the content of the variable p by means of the usage of that pointer itself. (*pr = 19; is a valid statement).
A little bit far...
This is the general idea behind behind a "more complex world".
The statement:
const int* ptr = &p;
it's possible because the a variable can be implicitly converted in its const version.
This question already has answers here:
What is the difference between const int*, const int * const, and int const *?
(23 answers)
Closed 6 years ago.
In the code below, why the returned pointer p is allowed to change? If f instead returns "const int *", then the compiler will complain type mis-match error at line "int *p =f()". Why does it do the same for "int * const"?
btw: I know there are memory leaks in the code, but that has nothing to do with the question.
int * const f() {
return new int(23);
}
int main(){
int * p=f();
p= new int(35);
return 0;
}
Because what you are returning is a unmodifiable pointer - not the pointer to unmodifiable data.
Yes, the returned pointer is not modifable - but it will never be modified! You are modifying the different pointer, p - which just happen to have the same value as your unmodifiable (and unnamed) pointer which is now gone - this object is a temporary and forgotten as soon as the statement is completed.
This is why returning const-qualified simple types by value from functions has no sense and actually triggers a warning in some compilers.
*const is a constant pointer while const * is a pointer to constant. The latter is immutable value; you can of course assign this value to a variable, like you would write int x = 42;. The former points at an immutable object, so assigning this to a variable that is supposed to point at a mutable object would presumably violate that object's constness.
In the code below, why the returned pointer p is allowed to change?
Because the type of p is int *. Since the pointer is not const, it may be modified. If you want p to not be modifiable, then you must make it const: int * const p
If f instead returns "const int *", then the compiler will complain type mis-match error at line "int *p =f()"
Pointer-to-const is not convertible to pointer-to-non-const. Such conversion is not allowed by the language because it would break const correctness.
Why does it do the same for "int * const"?
I guess you mean to ask "Why does the compiler allow assigning int * const to a int * variable?"
Copying a const object to a non-const object does not break const-correctness. When p is non-const, it's OK to modify it and the const temporary returned by f remains unmodified through it's entire (short) lifetime.
Constness of a temporary is rarely meaningful, and so is returning a top-level const value.
I was reading a C++ template example, and part of the template signature confused me.
Am I reading this correctly:
const T* const foo;
Is foo a const* to a const T?
Yes, it's a constant pointer to a constant T. I.e., you can neither modify the pointer, nor the thing it points to.
const T* would only forbid you to modify anything the pointer points to, but it allows you (within the bounds of the language) to inspect the value at *(foo+1) and *(foo-1). Use this form when you're passing pointers to immutable arrays (such as a C string you're only supposed to read).
T * const would mean you can modify the T value pointed to by foo, but you cannot modify the pointer itself; so you can't say foo++; (*foo)++ because the first statement would increment (modify) the pointer.
T * would give you full freedom: you get a pointer into an array, and you can inspect and modify any member of that array.
Yes; that is exactly what it means.
Since there is always a little confusion about const when using pointers, there are the following possibilities:
const T * aConstant
means aConstant is a variable pointer to a constant T.
T const * aConstant
does exactly the same.
T * const aConstant
declares that aConstant is a constant pointer to a variable T and.
T const * const aConstant (or const T * const aConstant)
declares a constant pointer to a constant T.
This is a const pointer-to-const T. So if T was an int, then array is a pointer to an int that is const in two ways:
pointer-to-const: the value that the pointer is pointing to cannot be changed (or pointing to const int)
const pointer: the memory address stored in the pointer cannot change
This is also the same as T const * const array
See wiki on const correctness.
Yes, foo is a constant pointer to constant T.
Yes.
const T*
makes the elements of the array const... at least, as far as foo is concerned.
foo[0] = T(); // Illegal!
foo[1] = T(); // Illegal!
foo[2] = whatever; // Illegal!
const
makes foo a constant pointer. Therefore, this is illegal:
foo = &some_array;
The variable
foo
...if you don't know what this is, you should seriously consider going to preschool.
Yes it is, i think name of var(const) is what stumbles you.
Yes, it just simply means that not only can't you change what foo points to, but you also can't change the value of foo itself so that it points to some other T instance.
simply parse it like this
const<ptr<const<T>>> foo
although it is illegal, but I think everyone can grasp its essence.
what does "T const *[]" as parameter
type mean?
What's the difference
compared to "T *[]"?
And as last
question: why can't I pass a "T *[]"
to a function that requires a "T
const * []" as parameter?
Thank you for your help.
Tobias
As a type in general, it's an array of pointers to a constant T.
Try putting a name in it:
T const *x[];
and apply the usual rules: [] binds tighter than *, so it's an
array. Then the * means that its an array of pointers, and
finally, they all point to a constant T. (As usual, const
modifies whatever is to the left of it.)
As a parameter, of course, an array type is converted to
a pointer type, so we end up with a pointer to a pointer to
a constant T. This could also be written:
T const **
If you drop the const, you end up with:
T **
which is not the same thing as T const**.
And the reason you can't pass a T** or a T*[] to the first
form is to prevent things like:
void f(int const* p1[]; int const* p2)
{
p1[0] = *p2;
}
int const x = 10;
int* px[1];
f(px, &x);
*px[0] = 20; // Where does this write?
The fact that the declarations are written using [] is, in this
case, misleading, since the rules for pointers to pointers still
apply.
It's an array of pointers to constant objects of type T (i.e. the pointer can change, but you cannot call a non-const function, or modify a non-mutable data member on these objects). T *[] is an array of pointers to non-const ojects. You can't pass T *[] to a function requiring a T const *[] as it would invalidate the const correctness of the pointers.
See here for more information.